2016-09-22 2 views
-2

Сегодня я делал упражнения по университетскому программированию и подошел к этой странной вещи. Я хотел бы знать, может ли кто-нибудь объяснить мне, что здесь происходит.Действительно странное взаимодействие с числами

Это вещь, которую я закодированы, чтобы показать:

program problema; 

var 

a : real; 
b : real; 

begin 

a := 1 - 0.8 - 0.2; 
b := 1 - 0.2 - 0.8; 

write(a); 
writeln(b); 

end. 

В то время как я ожидал, что он возвращает 0, в обоих случаях, это на самом деле возвращает -1.3 ... на первый и 0 на второй , Как это возможно?

+5

Возможный дубликат [Является ли математика с плавающей запятой?] (Http://stackoverflow.com/questions/588004/is-floating-point-math-broken) – JJJ

+0

Обратите внимание, что это не -1,3 ... но -1,3 ... E-020, который составляет -0,000 ... 13 (с 20 нулями). – JJJ

+0

Он оценивается как -5.55111512313e-17 в PHP и на моем настольном калькуляторе Fedora. Так что это широкий симптом компьютерной математики, а не просто паскаль. :) См. Это для ссылки на точный номер: http://matlab.wikia.com/wiki/FAQ#Why_is_0.3_-_0.2_-_0.1_.28or_similar.29_not_equal_to_zero.3F – SomeDude

ответ

0

Вы видите ошибки округления при работе с десятичными знаками, выраженными в двоичном формате. Другие комментаторы подразумевали это, но просто не говорили об этом конкретно.

Для решения этой проблемы важно оценивать равенство как диапазон, а не равенство. Например, чтобы решить, действительно ли действительное число x равно 0,2, протестируйте его не как x = 0.2, а скорее для | x-0.2 | < epsilon, где epsilon - это толерантность, которую вы хотите. Возможно, abs (x-0.2) < 0.000001 достаточно хорош.