Добро пожаловать! Войти Зарегистрироваться

Расширенный

Вопрос по вычислению машинного эпсилон

Написал privateer 
Здравствуйте.

Валентин Евгеньевич, разъясните пожалуйста немного по поводу вычисления машинного эпсилон и регулирования ширины таблицы на основании порядка числа, необходимого для выполнения курсовой работы. У меня FreeBSD 6.0 и два компилятора, Free Pascal и GNU Pascal. На лекции по курсовой Вы предложили взять за основу следующий пример вычисления машинного эпсилон -

program GetEpsilon(output);

var eps : real;

begin
eps := 1;
while (1+eps/2) > 1 do
begin
eps := eps/2;
end;
writeln ('machine epsilon =', eps : round(7-ln(eps)/ln(10)));
end.

Вопросы -

1. Такая форма указания количества выводимых значащих элементов применима только к gpc и compaq pc? Я получаю два различных результата

gpc -
machine epsilon = 2.2204460492503131e-16

fpc -
machine epsilon = 1.084202172485504E-019

Как видно fpc при такой форме вывода определяет количество знаков вывода, но выводимое число от этого точнее не выводит, просто заполняя предшествующие позиции пробелами. Или я что-то не верно понял?

Кроме того, форма вывода у fpc отилчается еще и количеством служебных символов в выводе - порядок указывается трехзначным числом, в данном случае как -019, при степени -5 как -005. Т.е. получается не очень устойчивая к компилятору форма вывода.

Кстати, интерестный факт - если я произвольно увеличу количество выводимых значащих символов числа, например следующим образом -
writeln ('machine epsilon =', eps : round(35-ln(eps)/ln(10)));

то получу следующий конечный результат -

machine epsilon = 2.22044604925031308084726333618164062500000000e-16

т.е. с точки зрения количества знаков более точное число. Ограничивая мантиссу в 16 знаков после запятой, значащие символы частично скрадываются. Хотя машина уже не может это число разделить на 2, т.к. цикл заканчивается, это число является последним результатом. А если еще выводить все промежуточные результаты, то очень интерестно наблюдать на какой границе начинают теряться значащие символы.

С уважением,
Шафирин Юрий.
гр. 18-101
В предыдущем посте не совсем отчетливо видно разницу между выводом программы компилированой fpc и gpc, пробелы между знаком = и первой цифрой удаляются форумом, поэтому я заменю их знаком "_" -

fpc (четыре пробела) -
privateer@FreeBSD01$ /home/privateer/geteps
machine epsilon =____1.084202172485504E-019

gpc (один пробел) -
privateer@FreeBSD01$ /home/privateer/a.out
machine epsilon =_2.2204460492503131e-16
zzz
Re: Вопрос по вычислению машинного эпсилон
08 January 2006 12:12
Привет, Юрий! Вы писали:

> Валентин Евгеньевич, разъясните пожалуйста немного по поводу
> вычисления машинного эпсилон и регулирования ширины таблицы на
> основании порядка числа,

на лекции мы разбирали только вычисление ширины поля для дробной части по машинному эпсилон!

> необходимого для выполнения курсовой
> работы. У меня FreeBSD 6.0 и два компилятора, Free Pascal и GNU
> Pascal. На лекции по курсовой Вы предложили взять за основу
> следующий пример вычисления машинного эпсилон -
>
> program GetEpsilon(output);
>
> var eps : real;
>
> begin
> eps := 1;
> while (1+eps/2) > 1 do
> begin
> eps := eps/2;
> end;
> writeln ('machine epsilon =', eps : round(7-ln(eps)/ln(10)));
> end.
>
Общую ширину поля мы только прикинули (+7), а на одном из семинаров продолжили изыскания в сторону полной вычислимости ширины.

> Вопросы -
>
> 1. Такая форма указания количества выводимых значащих элементов
> применима только к gpc и compaq pc? Я получаю два различных
> результата
>
> gpc -
> machine epsilon = 2.2204460492503131e-16
>
> fpc -
> machine epsilon = 1.084202172485504E-019
>
> Как видно fpc при такой форме вывода определяет количество
> знаков вывода, но выводимое число от этого точнее не выводит,
> просто заполняя предшествующие позиции пробелами. Или я что-то
> не верно понял?
>

Они используют разные вещественные типы (о вреде умолчаний!). Метод применим всегда, тем и полезен, что вычисляет точность фактически используемого типа.
> Кроме того, форма вывода у fpc отилчается еще и количеством
> служебных символов в выводе - порядок указывается трехзначным
> числом, в данном случае как -019, при степени -5 как -005. Т.е.
> получается не очень устойчивая к компилятору форма вывода.
>
> Кстати, интерестный факт - если я произвольно увеличу
> количество выводимых значащих символов числа, например
> следующим образом -
> writeln ('machine epsilon =', eps : round(35-ln(eps)/ln(10)));
>
> то получу следующий конечный результат -
>
> machine epsilon =
> 2.22044604925031308084726333618164062500000000e-16
>
> т.е. с точки зрения количества знаков более точное число.
Это число имеет ту же точность, а большинство его десятичных знаков после точки (с 17-ого по 44-й) неверные, это осколки (щепки, стружки) функции деинтерпретации внутреннего представления числа при выводе. Иногда для этого используется более точный вещественный тип, но это добавит не более 3-х знаков: вряд ли на Вашем домашнем компьютере имеется более чем 80-битная вещественная арифметика.

> Ограничивая мантиссу в 16 знаков после запятой, значащие
> символы

цифры!!

> частично скрадываются.

Они-то как раз и не значащие! Не может быть значимость шире мантиссы!!

> Хотя машина уже не может это
> число разделить на 2, т.к. цикл заканчивается, это число
> является последним результатом. А если еще выводить все
> промежуточные результаты, то очень интерестно наблюдать на
> какой границе начинают теряться значащие символы.
>
> С уважением,
> Шафирин Юрий.
> гр. 18-101
zzz
Re: Вопрос по вычислению машинного эпсилон
08 January 2006 12:12
privateer писал(а):

> В предыдущем посте не совсем отчетливо видно разницу между
> выводом программы компилированой fpc и gpc, пробелы между
> знаком = и первой цифрой удаляются форумом, поэтому я заменю их
> знаком "_" -
>
> fpc (четыре пробела) -
> privateer@FreeBSD01$ /home/privateer/geteps
> machine epsilon =____1.084202172485504E-019
>
> gpc (один пробел) -
> privateer@FreeBSD01$ /home/privateer/a.out
> machine epsilon =_2.2204460492503131e-16

fpc во всех умолчаниях, расширениях и сужениях следует Borland'у, а gpc имеет опции следования различным диалектам и стандартам Паскаля. Вывод в Паскале не стандартизован, но даже с помощью стандартных средств можно довольно тонко управлять им. В частности, на олимпиадах по программированию с автоматическим тестированием задач требуется точно выдерживать формат вывода.
Большое спасибо за ответы. Продолжаю работать над собой.

С уважением,
Юрий Шафирин.
гр.18-101
К сожалению, только зарегистрированные пользователи могут писать в этом форуме.

Авторизоваться на форуме