2013-04-18 1 views
-5

Почему он равен allways false?Попытка сравнить расчет по значениям float возвращает false

<?php 

$a = (0.1+0.2); 
print $a."\n"; // results in 0.3 
if ((double)$a == (double)0.3) { 
    echo "true"; 
}else{ 
    echo "not true"; 
} 
echo PHP_EOL; 

Perl

perl -e 'if ((0.2+0.1) == 0.3) {print "true\n"; } else { print "false\n"; }' 

И теперь в Python

python -c 'if ((0.2+0.1)!=0.3): print "false" ' 
+2

См 'Perl -e«Printf "% .20f% .20f", 0,1 + 0.2,0.3'' для просветления. – mob

ответ

1

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

Если вы хотите узнать больше о "плавает" и то, что IEEE 754 является, прочитать: http://www.floating-point-gui.de/

(Стандартный ответ для людей, которые сообщают о таких ошибках в http://bugs.php.net)

1

Enter в командной строке Python:

>>> 0.2 + 0.1 

вероятно, вы увидите:

0.30000000000000004 

0,2 и 0,1 не имеют точных представлений в двоичной плавающей запятой. Смотрите эту ссылку для подробностей:

http://docs.python.org/2/library/decimal.html

2

Вы должны указать допуск [также упоминается как epsilon] при сравнении значений с плавающей точкой, так как it is not an exact representation of the number.

function f_cmp(float $a, float $b, float $tol = 0.00001) { 
    if(abs($a - $b) < $tol) { return 0; } 
    else { return $a - $b; } 
    // return 0 if "equal" within tolerance 
    // return < 0 if $a < $b 
    // return > 0 if $a > $b 
    // for use with PHP functions like usort() 
} 

Или просто:

function f_eq(float $a, float $b, float $tol = 0.00001) { 
    if(abs($a - $b) < $tol) { return true; } 
    else { return false; } 
} 
Смежные вопросы