0

Я пытаюсь понять номера двойной точности в Matlab. Почему этот 1 - 3 * (4/3 - 1) не равен нулю?Объяснение 1 - 3 * (4/3 - 1) = 2.2204e-16 в Matlab

+6

Плавающая точка не представляет десятичных чисел точно. См. [Что каждый компьютерный ученый должен знать о арифметике с плавающей запятой] (https://ece.uwaterloo.ca/~dwharder/NumericalAnalysis/02Numerics/Double/paper.pdf). –

+1

Мое необоснованное предположение состоит в том, что из-за основного представления двойников он вычисляется как 2.22044604925031E-16. – lzcd

+0

также см. «Eps» в Matlab help – sridutt

ответ

6

Реальное число 4/3 не представляется в двойной точности (или в любом другом двоичном формате с плавающей запятой), поскольку оно не является диадическим рациональным. Таким образом, когда вы вычислить 4/3 в MATLAB, значение, которое вы получаете округляется до ближайшего представимому число двойной точности, что именно:

1.3333333333333332593184650249895639717578887939453125 

Вычитание 1 от этого значения является точным (это хорошо известная теорема FP ошибки-анализа, вычитания чисел в два раза друг с другом точно), поэтому результат 4/3 - 1 является:

0.3333333333333332593184650249895639717578887939453125 

случается, что результат умножения этого числа на три также точно представимо:

0.9999999999999997779553950749686919152736663818359375 

Наконец, вычитая из 1.0 также является точным (по теореме I ссылки ранее):

0.0000000000000002220446049250313080847263336181640625 

Таким образом, есть только один источник ошибок округления в вашем вычислении, в связи с тем, что 4/3 не может быть представлен как двойной, и конечным результатом вычисления является простое перенос начальной ошибки.

1

Запуск этого на научный калькулятор - журнал (2.2204e-16) - дает (почти) ровно -52. Другими словами, Matlab сохраняет 52 бита точности в double, а еще 5 бит для показателя (знак 4 +) и один для знака знака. Это соответствует реализации IEEE 754: 53 бит для знака (знак 52 +) и 5 ​​для экспоненты. Все хорошо! Как всегда, вы должны проверить, достаточно ли близки два числа с плавающей запятой, а не точно ли они равны. Соответствующий пример в Matlab будет выглядеть так:

if abs(x - y) < 1e-15 
     % Some code to execute when x and y are approximately equal 
else 
     % Some other code 
end 

Заявление соблюдения стандарта IEEE 754 происходит от the wikipedia article.

+0

Ого, мода увидела мой ответ. Это первый. –

+0

Кроме того, я отредактировал ответ выше, включив функцию «abs». Очень важно! –

0

Проблема начинается с расчета 4/3. Точный ответ представляется не в конечном числе десятичных цифр и не в конечном числе бит. Результат будет сохранен как 4/3+r, где r - это небольшое абсолютное знаковое число, обозначающее разницу между реальным значением 4/3 и ближайшим 64-битным двоичным поплавком IEEE 754 до 4/3, погрешностью округления.

Вычитание 1 результатов в 1/3+r. Умножение на 3 получает 1+3r. Вычитая его из 1, получаем -3r.

Конечный результат -3-кратная ошибка округления в исходном представлении 4/3.

Смежные вопросы