Арифметическая точность с двойными числами в Matlab - PullRequest
5 голосов
/ 13 сентября 2010

У меня возникли некоторые проблемы с пониманием того, как точность этих двойных чисел влияет на результат арифметических операций в Matlab.Я думал, что, поскольку оба a & b являются двойными, они смогут выполнять операции с такой точностью.Я понимаю, что может быть ошибка округления, но так как эти числа находятся в пределах представления 64-битных чисел, я не думал, что это будет проблемой.Точность распознавания! = 0, но при добавлении к 1 не показывает никаких изменений.

Ответы [ 3 ]

6 голосов
/ 13 сентября 2010

«Плавающая» точка означает только то, что точность относится к шкале самого числа.

В приведенном вами конкретном примере 1.22e-45 можно представить отдельно, поскольку показатель степени может бытьс поправкой на 10 ^ -45 или приблизительно 2 ^ -150.

С другой стороны, 1.0 представляется в двоичном виде со шкалой 2 ^ 0 (т. е. 1).

Для добавленияэти два значения, вам нужно выровнять их десятичные точки (er ... двоичные точки), а это означает, что вся точность 1.22e-45 сдвинута на 150 с лишним битов вправо.

Конечно,Значения с плавающей точкой двойной точности IEEE имеют только 53 бита мантиссы (точности), что означает, что в масштабе 1,0, 1.22e-45 фактически равен нулю.

6 голосов
/ 13 сентября 2010

64-битные числа с плавающей точкой IEEE-754 имеют достаточную точность (с 53-битной мантиссой), чтобы представлять около 16 значащих десятичных цифр. Но это требует больше, как 45 значащих десятичных цифр сказать разницу между (1 + a) = 1.00 .... 000122 и 1.000 для вашего примера.

3 голосов
/ 13 сентября 2010

Чтобы добавить к тому, что сказали другие ответы, вы можете использовать функцию MATLAB EPS , чтобы визуализировать проблему точности, с которой вы столкнулись. Для заданного числа с плавающей запятой двойной точности функция EPS сообщит вам расстояние от него до следующего наибольшего представимого числа с плавающей запятой:

>> a = 1.22e-45;
>> b = 1;
>> eps(b)

ans =

  2.2204e-016

Обратите внимание, что следующее число с плавающей запятой, большее 1, равно 1.00000000000000022204 ... и значение a даже близко не достигает половины расстояния между двумя числами. Следовательно, a+b в итоге остается 1.

Кстати, вы также можете понять, почему a считается ненулевым, даже если он настолько мал, если взглянуть на наименьшее представимое значение с плавающей запятой двойной точности, используя функцию REALMIN :

>> realmin

ans =

  2.2251e-308  %# MUCH smaller than a!
...