提问人:Brett 提问时间:8/30/2018 更新时间:8/30/2018 访问量:395
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端对这个数字进行测试,看看它们是否匹配,所以我尝试了这个(例如):
PHP格式:
$item = 25.00;
$postage = 24.99;
echo ((item + $postage) * 100); // 4999
因此,正如您所看到的,与 JavaScript 不同的结果 - 我是否可以依靠这是“正确的”进行比较,而不是以类似的东西结束?4998.999999999999
出于兴趣的缘故,我尝试应用与JavaScript类似的技术,使用JS在其函数中使用的类似方法,包括:toFixed
$number = (($item + $postage) * 100);
$expo = pow(10,0);
$number = intval($number * $expo) / $expo;
echo $number; // 4998
...我得到了而 JS 得到了 - 那么我应该坚持实际得到的结果吗?这可以信赖吗?4998
4999
4999
..还是你必须走这样的极端?
$res = (($item + $postage) * 100);
$res = (float) number_format($res, 0, '.','');
echo $res; // 4999
我的用例是我需要将浮点数(美元)转换为美分,然后将它们从客户端到服务器端进行比较。
答:
1赞
Devon Bessemer
8/30/2018
#1
简单回答:不。你不能依赖PHP或任何语言中的浮点精度。虽然它可能适用于此示例,但在某些情况下它不匹配。
如果需要精度,请使用整数进行数学运算,或者将 bcadd() 与字符串一起使用。
如果足够接近就可以了,你应该能够摆脱 round()。number_format() 不适合用于比较,只能用于格式化(参见千位分隔符)。
评论
0赞
Brett
8/30/2018
所以你的意思是对JS和PHP的结果使用round?我只需要把数字变成整分,没有小数点和你期望的结果。(item + postage) * 100
0赞
Devon Bessemer
8/30/2018
是的,虽然不精确,但对于您的用例来说,在两种语言中四舍五入到整数可能就足够了。
评论
bcmath
库。如果您的应用程序中需要精确的浮点运算,则应使用各种函数并确保指定精度刻度。bcmath
math.js
进行准确的 JS 算术。我还没有验证,但我是 99.989999999999999948840923025273% (PHP 98.99+1) 肯定您的解决方案会在某个时候光荣地失败。.toFixed()