Ошибка с плавающей точкой в ​​MATLAB - линейно разнесенные векторы

ОС: Win 7 64bit. Matlab: 2014a, 2015a

Когда я создаю вектор следующим образом:

a = 0.2:0.2:1

Я получил:

a = 0.2000    0.4000    0.6000    0.8000    1.0000

что ожидается. Теперь, когда я хочу увидеть, существует ли 0,6 в моем векторе, я печатаю:

a == 0.6

и я получаю: 0 0 0 0 0

find(a == 0.6) также вернуть Empty matrix: 1-by-0

Это неожиданно. Он может найти все остальные значения, но для 0.6 есть проблема. Я думаю, что хотя 0,6 создается, это на самом деле 0,600000000000000001 или что-то подобное, что является проблемой. Вы можете видеть, что это a > 0.6 и получит 0 0 1 1 1,

1-Во-первых, почему это происходит?

2-во-вторых, можем ли мы увидеть полное значение числа в Matlab, если да, то какова функция или настройка для этого?

Я создал тот же вектор, используя linspace, но это тоже не помогло. Я нашел решение для этого, набрав: a = roundn(a, -10), Тем не менее, я думаю, что такое решение даже не нужно вообще.

3-Есть ли лучший способ заказать Matlab для получения точных значений?

Спасибо за вашу помощь.

1 ответ

Решение

Сначала прочтите документацию MATLAB по значениям с плавающей запятой, обратив особое внимание на раздел об ошибках и точности с плавающей запятой: MATLAB Floating Point

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

>> a = 0.6;
>> b = 0.6;
>> a == b
   ans = 1

Вместо этого вы эффективно сравниваете:

>> a = 0.6;
>> b = 0.2 + 0.2 + 0.2;
>> a == b
   ans = 0

Причиной очевидной логической ошибки здесь является то, что арифметика на самом деле не равна. Ценности 0.6 а также 0.2 оба представлены в виде числа с плавающей запятой двойной точности для максимально возможного значения CLOSEST, разницы, известной как "ошибка с плавающей запятой".

Наблюдать за ошибкой просто:

>> a = 0.6;
>> b = 0.2 + 0.2 + 0.2;
>> a - b
   ans = -1.110223024625157e-16

Самое простое решение - использовать round() на вашем скаляре и векторе с одинаковой точностью, затем выполните сравнение:

>> a = 0.6;
>> b = [ 0.2 : 0.2 : 1 ];
>> roundn ( a , -10) == roundn ( b , -10 )
   ans = 0 0 1 0 0
Другие вопросы по тегам