2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




 
 Машинный нуль
Сообщение16.11.2009, 21:06 
Дана задача протабулировать точки на неком интервале с точностью эпсилон, где эпсилон машинный нуль на интервале 1.0.

Находим его за простым алгоритмом

int main() /*Computer Zero*/
{
long A;
double D;

A = 1;

D = 0.5;

while (A + D != A)
D = D * 0.5;

1. Очевидно, что разница следующей точки некоего интервала от предыдущей должна быть больше машинного нуля, если мы двигаемся вправо. Вопрос в том, как мы используем машинный нуль в качестве точности при табулировании?

2. В теории говорится, что для каждого числа существует свой машинный нуль, а на практике (при компиляции) подходит для целых чисел разных порядков. В чем я не прав? Буду рад любым ссылкам на материалы.

Заранее извиняюсь за возможно не совсем четкую формулировку вопросов.

 
 
 
 Re: Машинный нуль
Сообщение16.11.2009, 21:15 
Ваша программа может найти неправильное значение.
В некоторых случаях локальные вычисления типа double будут сделаны с большей точностью, например как 80-битные числа с 64-битной мантиссой (long double на GCC).

Попробуйте воспользоваться не совсем стандартной функцией nextafter() если она у вас есть.

double nextafter(double x, double y);

DESCRIPTION
The nextafter() functions return the next representable
neighbor of x in the direction towards y. The size of the
step between x and the result depends on the type of the
result. If x = y the function simply returns y. If
either value is NaN, then NaN is returned. Otherwise a
value corresponding to the value of the least significant
bit in the mantissa is added or subtracted, depending on
the direction.

 
 
 
 Re: Машинный нуль
Сообщение16.11.2009, 21:31 
Alex696 в сообщении #262703 писал(а):
2. В теории говорится, что для каждого числа существует свой машинный нуль, а на практике (при компиляции) подходит для целых чисел разных порядков. В чем я не прав?
А на каком компиляторе?
В VS2008 для разных A получаются разные нули:
Код:
      1 1.110223e-016
     10 8.881784e-016
    100 7.105427e-015
   1000 5.684342e-014
  10000 9.094947e-013
  100000 7.275958e-012
1000000 5.820766e-011

 
 
 
 Re: Машинный нуль
Сообщение17.11.2009, 14:40 
venco в сообщении #262708 писал(а):
Ваша программа может найти неправильное значение.
В некоторых случаях локальные вычисления типа double будут сделаны с большей точностью, например как 80-битные числа с 64-битной мантиссой (long double на GCC).

Ну и что? Естественно, понятие машинного нуля привязано к формату хранения данных. "Правильное" значение для одного формата будет неправильным для другого, и никакая программа вообще тут ничего не изменит.

 
 
 
 Re: Машинный нуль
Сообщение17.11.2009, 17:19 
Maslov в сообщении #262716 писал(а):
Alex696 в сообщении #262703 писал(а):
2. В теории говорится, что для каждого числа существует свой машинный нуль, а на практике (при компиляции) подходит для целых чисел разных порядков. В чем я не прав?
А на каком компиляторе?
В VS2008 для разных A получаются разные нули:
Код:
      1 1.110223e-016
     10 8.881784e-016
    100 7.105427e-015
   1000 5.684342e-014
  10000 9.094947e-013
  100000 7.275958e-012
1000000 5.820766e-011


Компилятор CodeBlocks.

 
 
 
 Re: Машинный нуль
Сообщение17.11.2009, 17:28 
ewert в сообщении #262931 писал(а):
Ну и что? Естественно, понятие машинного нуля привязано к формату хранения данных. "Правильное" значение для одного формата будет неправильным для другого, и никакая программа вообще тут ничего не изменит.
Да я вообще не понял о чём вопрос. Указал только на неправильность программы. :)

 
 
 
 Re: Машинный нуль
Сообщение17.11.2009, 18:37 
Alex696 писал(а):
Дана задача протабулировать...

Если хотите грамотно работать с вещественной арифметикой, советую ознакомиться с функцией dlamch из пакета lapack.

 
 
 
 Re: Машинный нуль
Сообщение17.11.2009, 20:27 
venco в сообщении #262974 писал(а):
Указал только на неправильность программы.

Дык она ж правильная. Для фиксированного формата.

И для фиксированного "А", для которого пытаются получить тот ноль. А без хоть одной из этих фиксаций задача -- и вовсе бессмысленна.

 
 
 
 Re: Машинный нуль
Сообщение18.11.2009, 12:20 
Аватара пользователя
С какой целью у вас A и D разного типа? Какого типа у вас A + D и A в while? Надо определиться, какой длинны у вас данные.
Машинный ноль наверное всё же в окресности 0, когда порядок минимальный и записан в описании типа данных. Расстояние между числами с плавающей точкой (погрешность), зависит от порядка, и в окресности 1 он скорее всего не минимальный.
По-моему порядок чисел на котором происходит выход из цикла после операции D*0.5 несколько случаен и в процесс вмешивается операция округления.
Для определения погрешности числа с плавающей точкой нужно знать кроме длины мантиссы величину порядка этого числа. В пределах одного порядка погрешность (расстояние между числами) фиксирована и определяется той длинной мантиссы, которую выделяет для этих данных компилятор. Относительную погрешность для чисел с плавающей точкой можно считать постоянной.
Почитайте Дейкстру на этот случай.

 
 
 [ Сообщений: 9 ] 


Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group