2011-04-07 64 views
4

我想我已经看了太久。为什么这个代码打印'不',它应该打印'是'不应该吗?我已经在PHP 5.3和PHP 5.2上尝试过了,并且都打印出'不'。非常简单的PHP添加问题

<?php 

$total = 14.05; 
$var1 = 0; 
$var2 = 0.11; 
$var3 = 13.94; 

if(($var1 + $var2 + $var3) == $total) 
{ 
    echo 'yes'; 
} 
else 
{ 
    echo 'no'; 
} 

?> 
+5

**从不**比较直接相等的浮点值。这里有很多关于SO的问题。 – Jon 2011-04-07 14:38:00

+3

可能是相关的:[每个计算机科学家应该知道什么关于浮点运算](http://download.oracle.com/docs/cd/E19957-01/806-3568/ncg_goldberg.html) – eldarerathis 2011-04-07 14:38:23

+1

看到这个:http: //stackoverflow.com/questions/3148937/compare-floats-in-php/3148991#3148991 – dusan 2011-04-07 14:38:38

回答

0

因为..你要平等比不上彩车......这是一个四舍五入的问题...像14.05实际上是表示为14.0499999 ......所有你能做的事情将有一定tolarence进行比较,例如t = 0.01,那么如果a + t> = b> = a-t,a = b将被视为真。

2

像其他人一样,不要直接比较花车。 只是做一个 如果(ABS($ float1- $ FLOAT2)< 0.0000001)

或similair

在你的情况

<?php 

$total = 14.05; 
$var1 = 0; 
$var2 = 0.11; 
$var3 = 13.94; 

if (abs(($var1 + $var2 + $var3)-$total)<0.000001) 
{ 
    echo 'yes'; 
} 
else 
{ 
    echo 'no'; 
} 

?> 
0

我怀疑这是由于floating point precision

基本上浮点数不能以完全精度进行存储,有时结果不符合您的期望。为了比较浮点数,你应该允许一些容差。如果你确定每个数字都有两个小数位,你可以乘以100来得到整数值,然后比较总数。

0

这是由浮点精度引起的。浮点数表示实际值,但仅表示一定的精度。而不是尝试以下操作:解决此

<? 
$total = 14.05; 
$var1 = 0; 
$var2 = 0.11; 
$var3 = 13.94; 

if((($var1 + $var2 + $var3) > ($total - 0.0000001)) && (($var1 + $var2 + $var3) < ($total + 0.0000001))) 
{ 
    echo 'yes'; 
} 
else 
{ 
    echo 'no'; 
} 
?> 
1

一个很懒惰的方式:

$var4 = $var1 + $var2 + $var3; 
$var4 = number_format($var4, 2); 
$total = number_format($total, 2); 

if($var4 == $total) 
{ 
    echo 'yes'; 
} 
else 
{ 
    echo 'no'; 
} 

http://php.net/number_format

0

这是一个基本的浮点数学问题。

电脑使用二进制数学运算。对于整数值,没有问题。但是对于小数,它使用了一种称为浮点数学的技术。麻烦的是,虽然浮点数是好的,但不要直接映射到十进制值;即使相对简单的十进制值可能也无法用二进制精确表示。

如果您总是使用两位小数 - 例如对于货币 - 将整个值作为整数处理通常是一个更好的主意(例如,存储美分而不是美元,或便士而不是磅),以便所有你的数学是用整数完成的,结果是准确的。你只需要它作为显示目的的小数,你可以在你需要的时候做。

1

如果您需要做精确的浮点运算了很多,它使用库像GMPBCMath

0

浮点值具有有限的精确度的价值。因此,值可能 任何处理后不具有相同的字符串表示形式。这也 包括写在你的脚本中的浮点值,并直接打印它没有任何数学运算。

如果您想了解更多关于“花车”,什么IEEE 754,读这样的:

http://docs.sun.com/source/806-3568/ncg_goldberg.html

可以使用number_formattig或字符串铸造comperation

1

之前,正如上文其他答案,比较浮动时要小心。试试这个:

echo ((int)(($var1+$var2+$var3)-$total)==0)?"yes":"no";