JavaScript 和 PHP 中的浮点数加法和一致性

Addition with floating point numbers in JavaScript and PHP and consistancy

我相信很多人都经历过,我在浮点数学方面遇到了一点问题 - 我在 JavaScript 中解决了这个问题,但是同时它 似乎 在 PHP 中没问题 我想确保它可以被依赖,因为它与 JS 版本略有不同。

JavaScript:

var item = 25.00;
var postage = 24.99;

((item + postage) * 100) // 4998.999999999999

显然我不想要这个,我想要 49.99,所以我改成这样:

((item + postage) * 100).toFixed(0) // 4999 (string)

然后我把它改成这样:

provideFloat((book_price + shipping_cost) * 100).toFixed(0)) // 4999 (float)

function provideFloat(num) {
    return parseFloat(num.replace(/,/g, ''));
}

现在,我需要在 PHP 一侧测试 against 这个数字,看看它们是否匹配,所以我尝试了这个(例如):

PHP:

$item = 25.00;
$postage = 24.99;

echo ((item + $postage) * 100); // 4999

如您所见,结果与 JavaScript 不同 - 我可以依靠这个 "right" 来进行比较,而不是像 4998.999999999999 这样的结果吗?

出于兴趣的缘故,我尝试将我在 JavaScript 中使用的类似技术应用到 JS 在其 toFixed 函数中使用的 similar approach,其中:

$number = (($item + $postage) * 100);
$expo = pow(10,0);
$number = intval($number * $expo) / $expo;

echo $number; // 4998

...我得到 4998 而 JS 得到 4999 - 那么我应该坚持实际得到 4999 结果的结果吗?这个靠谱吗?

..还是必须走极端?

$res = (($item + $postage) * 100);
$res = (float) number_format($res, 0, '.','');
echo $res; // 4999

我的用例是我需要将浮点数(美元)转换为美分,然后从客户端到服务器端进行比较。

简单回答:不。您不能依赖 PHP 或任何语言中的浮点精度。虽然它可能适用于此示例,但在某些情况下它会不匹配。

如果需要精度,请将整数用于数学运算或将 bcadd() 用于字符串。

如果足够接近就好了,你应该能够摆脱 round()。 number_format() 不适用于比较,只能格式化(请参阅千位分隔符)。