PHP数学奇怪的行为

时间:2013-12-02 07:26:16

标签: php

我的代码中有幻影错误。它出现在10次尝试的一个案例中。当我尝试调试它时,我发现了这种奇怪的行为:

$a = floor(1385968017.8665 * 10000); // or (int) (1385968017.8665 * 10000)
// here $a equals to 13859680178664
$b = (1385968017.8665 * 10000);
// here $b equals to 13859680178665

我有这样的PHP版本/配置:

PHP 5.3.10-1ubuntu3.8 with Suhosin-Patch (cli) (built: Sep  4 2013 20:00:51) 
Copyright (c) 1997-2012 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2012 Zend Technologies
with Xdebug v2.2.3, Copyright (c) 2002-2013, by Derick Rethans

更新 我知道浮动操作的原因。 C ++中的相同代码:

#include <iostream>

int main()
{
    std::cout << std::fixed << (1385968017.8665 * 10000) << std::endl;
    std::cout << (unsigned long long) (1385968017.8665 * 10000) << std::endl;

    return 0;
}

给我下一个输出:

13859680178664.998047
13859680178664

这是我对它的期望。但为什么我的PHP代码显示(1385968017.8665 * 10000)精确等于13859680178665?

更新2: 正如评论中提到的用户@ core1024,PHP可能是舍入计算结果(1385968017.8665 * 10000)。如果尝试php -r 'printf("%f\n",1385968017.8665 * 10000);'结果将在13859680178664.998047左右。谁可以解释PHP何时以及为何这样做?

3 个答案:

答案 0 :(得分:2)

按预期运行。

您在第一个语句中使用了FLOOR()函数, ROUNDS DOWN 一个值为最接近的整数。

检查here以获取更多信息。

至于为什么它会像这样四舍五入,这是因为你的价值1385968017.8665不是完全。 Jon Skeet解释说here ..与Tony the Pony一起。

答案 1 :(得分:0)

那是因为1385968017.8665是二进制的无限双, 和(字面1385968017.8665)〜=(计算机中的1385968017.8664998)。

圆形(1385968017.8665 * 10000)你需要什么?

答案 2 :(得分:0)

我找到了解决这个问题的方法。我的php.ini精度设置等于14.如果我将精度设置增加1,则不表示此stragne行为:

$a = floor(1385968017.8665 * 10000); // or (int) (1385968017.8665 * 10000)
// here $a equals to 1385968017866(!)5