我确信很多人都经历过,我在浮点数学上遇到了一个小问题-我在 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端再次测试 这个数字以查看它们是否匹配,因此我尝试了此操作(例如):
PHP:
$item = 25.00;
$postage = 24.99;
echo ((item + $postage) * 100); // 4999
如您所见,结果与JavaScript截然不同-我可以依靠这种“正确”来进行比较,而不以4998.999999999999
之类的词结尾吗?
出于兴趣的缘故,我尝试将JavaScript使用的类似技术与similar approach(JS在其toFixed
函数中使用的link)一起应用:
$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
我的用例是我需要将浮点数(美元)转换为美分,然后从客户端到服务器端进行比较。
答案 0 :(得分:1)
简单答案:不。您不能依赖PHP或任何语言的浮点精度。尽管此示例可能适用,但在某些情况下可能会不匹配。
如果需要精度,请对数学使用整数或对字符串使用bcadd()。
如果足够接近就可以了,您应该可以使用round()。对于比较而言,number_format()不适合用于比较,而仅用于格式化(请参阅千位分隔符)。