2010-11-21 94 views
5

echo (int) ((0.1+0.7) * 10);PHP整数舍入问题

为什么上面的输出是7?我理解PHP如何向0进行舍入,但不是将(0.1+0.7) * 10评估为浮点数,然后将其作为整数进行转换?

谢谢!

+0

我认为这发生在任何语言,因为浮点数的处理方式是内部的 – Quamis 2010-11-21 07:37:00

回答

7

当小数内部转换为二进制等效值时,会出现精度损失。计算出的值将类似于7.9+而不是预期的8.

如果您需要高度的准确性,请使用GMP函数族或bcmath函数库。

+0

+1像'bcmath'这样的库是最好的选择。 – 2010-11-21 02:46:15

0

我没有安装PHP,但在python:

$ python 
>>> 0.1+0.7 
0.79999999999999993 
>>> 

不在基地10所有号码可恰恰在基地2系统来表示。检查维基百科条目:二进制

部分分数。特别是,这条线:

Fraction Decimal  Binary Fractional Approx. 
1/10 0.1  0.000110011... 1/16+1/32+1/256... 

1/10不能在基座2。因此一个有限的方式来表示,0.1 + 0.7不能精确在碱计算2.

决不假设浮点点计算是精确的,它会迟早咬你。

2

参见手册:

http://php.net/manual/en/language.types.float.php

典型的是简单的小数 馏分像0.1或0.7不能 转化为它们的内部二进制 同行而不 精度小的损失。这可能导致混淆 结果:例如, floor((0.1 + 0.7)* 10)通常将 返回7而不是预期的8, ,因为内部表示将 类似7.9。

0

1/10不能用有限数量的二进制数字表示,就像1/3不能表示为有限数量的基数为10的数字一样。所以你实际上加在一起0.09999999999999 ...和0.69999999999999 ... - 总和是差不多是 8,但不是很完美。

1

其他答案解释为什么会发生这种情况。这应该得到你想要的东西:

echo (int) round((0.1+0.7) * 10); 

只是浮动强制转换为int之前。

+0

另外,它的建议你实际上并没有使用浮点数进行货币计算,因为这种精度的损失 – Quamis 2010-11-21 07:36:04