Учитывайте это (MATLAB R2011a):
a = 1e10;
>> b = inv(a)*inv(a)
b =
1.0000e-020
>> c = inv(a*a)
c =
1.0000e-020
>> b==c
ans =
0
>> format hex
>> b
b =
3bc79ca10c924224
>> c
c =
3bc79ca10c924223
Когда MATLAB вычисляет промежуточные величины inv(a)
или a*a
(является ли a
скалярной или матрицей), он по умолчанию сохраняетони как ближайшее число с плавающей запятой двойной точности - что не точно.Поэтому, когда эти немного неточные промежуточные результаты используются в последующих вычислениях, возникает ошибка округления.
Вместо сравнения чисел с плавающей запятой для прямого равенства, например inv(A*B*C) == inv(C)*inv(B)*inv(A)
, часто лучше сравнивать абсолютную разницудо порога, такого как abs(inv(A*B*C) - inv(C)*inv(B)*inv(A)) < thresh
.Здесь thresh
может быть произвольным небольшим числом или некоторым выражением, включающим eps
, что дает вам наименьшее различие между двумя числами с точностью, с которой вы работаете.
Только команда format
управляет отображением результатов в командной строке, а не способом внутреннего хранения результатов.В частности, format rat
не заставляет MATLAB выполнять вычисления символически.Для этого вы можете взглянуть на Symbolic Math Toolbox .format hex
часто даже более полезен, чем format long
, для диагностики проблем точности с плавающей запятой, например той, с которой вы столкнулись.