这是浮点行为还是PHP中的错误?

时间:2014-09-08 23:57:24

标签: php debugging floating-point

澄清:这不是在问我为什么会出现舍入错误。我知道这是一个错误或疏忽。这个问题询问为什么它在第一个var_dump中打印为整体,但是转换就好像它是57916.9重复并截断表示.9重复。

发生以下情况:

你接受一个包含值579.17的字符串(或浮点数 - 无关紧要)并将其乘以100.它var_dumps预期的57917.不是57916.99999999999999999999999或类似的。在我看来,var_dump不应该将任何东西舍入为调试函数。它可能必须截断,但在调试函数中舍入是意外的。

但是,如果然后将其转换为整数,则会从var_dump中获得意外的57916。

我知道浮点数的问题,但是在PHP中投射浮点数的行为显然是57917,显然有效地减去1.这是一个非常小的数字。

这似乎只发生在某些数字上,例如579.17。我测试的其他人不会发生这种情况。我们所做的只是将数字乘以100以发送到期望分数的API。 API库可以理解地转换为整数,因为API不接受小数分数。

测试用例:

php -r '$n = ("579.17" * 100); var_dump($n, (int)$n);'

输出:

float(57917)
int(57916)

环境:

x86-32,
x86-64 both.

3 个答案:

答案 0 :(得分:1)

使用round()代替int()579.17 * 100的实际值类似于57916.99999var_dump()将此显示为57917,但是当您使用int()时,它会截断该分数。使用round()将转到最接近的整数,而不是总是截断。

答案 1 :(得分:1)

var_dump使用php.ini中的precision来显示浮点值。你可以举起来看看会发生什么。

php -r 'ini_set("precision", 20); $n = ("579.17" * 100); var_dump($n, (int)$n);'
// double(57916.999999999992724)
// int(57916)

另外。无论是x86还是x64。 PHP使用64位浮点数。

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

答案 2 :(得分:0)

我认为这是因为硬件无法真实准确地表达浮点数。所以看起来像579.17实际上更像是579.16999999。因此,当你将它相乘并将其转换为int时,它会截断小数,然后使用57916。

相关问题