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

JavaScript和PHP中浮点数字的加法和一致性,javascript,php,floating-point,floating-accuracy,Javascript,Php,Floating Point,Floating Accuracy,我相信很多人都有过这样的经历,我在浮点数学方面遇到了一个小问题——我用JavaScript解决了这个问题,但是在PHP中它看起来还可以,我想确保它可以被依赖,因为它与JS版本略有不同 JavaScript: var item = 25.00; var postage = 24.99; ((item + postage) * 100) // 4998.999999999999 $item = 25.00; $postage = 24.99; echo ((item + $postage) *

我相信很多人都有过这样的经历,我在浮点数学方面遇到了一个小问题——我用JavaScript解决了这个问题,但是在PHP中它看起来还可以,我想确保它可以被依赖,因为它与JS版本略有不同

JavaScript:

var item = 25.00;
var postage = 24.99;

((item + postage) * 100) // 4998.999999999999
$item = 25.00;
$postage = 24.99;

echo ((item + $postage) * 100); // 4999
显然我不想要这个,我想要
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, ''));
}
那么为了更好的衡量,我将其改为:

((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:

var item = 25.00;
var postage = 24.99;

((item + postage) * 100) // 4998.999999999999
$item = 25.00;
$postage = 24.99;

echo ((item + $postage) * 100); // 4999
因此,正如您所看到的,与JavaScript不同的结果——我可以相信这是比较的“正确”结果,而不是以类似
4998.9999999999
的结果结束吗

出于兴趣,我尝试应用与JavaScript类似的技术,JS在其
toFixed
函数中使用了:

$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()不适合用于比较,仅用于格式化(请参见千位分隔符)。

我还没有通读整个问题,因为它很长,但我没有提到使用库。如果应用程序中需要精确的浮点运算,则应使用各种
bcmath
函数,并确保指定精度刻度。此外,还应使用精确的JS运算。我还没有验证,但我99.9899999999948840923025273%(PHP98.99+1)肯定您的解决方案在某一点上会失败。谢谢-我的意思是我确实希望它是准确的,但更重要的是双方都是准确的/返回相同的结果。@MonkeyZeus Ha。。。。。。确切地说,为什么我要求澄清我目前所做的事情是否可靠。我很难过地看到,你忽略了那些帖子中讨论的所有其他内容。我还没有验证,但是
.toFixed()
解决方案不可靠,因为它在执行浮点运算后对数字进行四舍五入,因此您是四舍五入的,结果不正确。您的“解决方案”围绕着格式化结果,而不是计算的准确性。垃圾进就是垃圾出;我不在乎你在那只猪身上涂了多少口红,你是说在JS和PHP两个版本中,使用<代码>(条目+邮资)* 100 < /代码>的结果?我只需要将数字转换成整分,不需要小数,以及您期望的结果。是的,虽然不精确,但两种语言的整数四舍五入可能就足以满足您的用例。