JavaScript添加十进制数问题
所以我正在制作一个脚本,将两个数字(十进制数)相加,我遇到了一个问题 我做了剧本,结果很好:JavaScript添加十进制数问题,javascript,numbers,Javascript,Numbers,所以我正在制作一个脚本,将两个数字(十进制数)相加,我遇到了一个问题 我做了剧本,结果很好: 0.1 + 0.5 //0.6 0.2 + 0.3 //0.5 但很快我就明白了: 0.1 + 0.2 //0.30000000000000004 0.01 + 0.06 //0.06999999999999999 在我看来,这是不对的。我知道将浮点与有限位一起使用是一个缺点,但我找不到一种方法来解决这个问题 Math.ceil //No Math.floor //No .slice
0.1 + 0.5 //0.6
0.2 + 0.3 //0.5
但很快我就明白了:
0.1 + 0.2 //0.30000000000000004
0.01 + 0.06 //0.06999999999999999
在我看来,这是不对的。我知道将浮点与有限位一起使用是一个缺点,但我找不到一种方法来解决这个问题
Math.ceil //No
Math.floor //No
.slice //No
更新
是否可以先将数字乘以1000,然后将其相加,再除以1000?使用
toFixed
将其转换为一个去掉小数点的字符串,然后再将其转换回一个数字
+(0.1 + 0.2).toFixed(12) // 0.3
看起来IE的toFixed
有一些奇怪的行为,所以如果您需要支持IE,这样做可能更好:
Math.round((0.1 + 0.2) * 1e12) / 1e12
这是浮点的常见问题 将
toFixed
与parseFloat
结合使用
以下是JavaScript格式:
function roundNumber(number, decimals) {
var newnumber = new Number(number+'').toFixed(parseInt(decimals));
return parseFloat(newnumber);
}
0.1 + 0.2; //=> 0.30000000000000004
roundNumber( 0.1 + 0.2, 12 ); //=> 0.3
测试此Javascript:
var arr = [1234563995.721, 12345691212.718, 1234568421.5891, 12345677093.49284];
var sum = 0;
for( var i = 0; i < arr.length; i++ ) {
sum += arr[i];
}
alert( "fMath(sum) = " + Math.round( sum * 1e12 ) / 1e12 );
alert( "fFixed(sum) = " + sum.toFixed( 5 ) );
var-arr=[1234563995.72112345691212.7181234568421.589112345677093.49284];
var总和=0;
对于(变量i=0;i
结论
不要使用Math.round((#+#+#+…+#+)*1e12)/1e12
相反,请使用(##+#+…+##+).toFixed(5))
在IE 9中,
toFixed
工作得很好。这不是一个bug,简单的实值有固定的精度,所以对实值进行计算可能会导致一些小错误。Math.round(0.1+0.2)
是0。@Gazler-我需要如何修复它,而不是它为什么会发生。解决这个问题的方法是对整数执行操作。所以,如果你在研究货币价值,不要用美元,而是用美分。(在计算结束时,只需除以100即可得到美元值)。@Gazler祝贺:)。当然,您将应用一些数学来确定所需的精度。另一方面,每个人都理解问题中的问题,但有一点我不清楚:预期的结果是什么?很好,很有效:@Derek在阅读了一些与问题相关的评论后,发现IE的toFixed可能会被截断而不是取整。这样做可能更安全:Math.round((0.1+0.2)*1e12)/1e12
@GGGMath.round()
是个好主意:)@GGG-看起来这是最终的解决方法。谢谢@可能吧。您的toFixed
解决方案在这里仍然有效:尝试11200030006000.125+0.001您是对的,KooiInc,我将其更新为12位精度。仍然是GGG的数学解决方案。round((0.1+0.2)*1e12)/1e12是优雅的解决方案!但现在的结果是:11200030006000.125+0.001=11200030006000.127
。应该是11200030006000.126……真奇怪。我还尝试了GGG的解决方案(),它的计算结果也是11200030006000.127。你知道为什么会发生这种情况吗?对于这么大的数字,我认为这只是精度的问题,而不是在二进制中重复小数<代码>100000000000.126==100000000000.127//true请给出结果的示例,或者至少创建一个提琴你的结论是什么?新的数字((11200030006000.125+0.001)。toFixed(5))仍然=11200030006000.127,但是如果你把它作为字符串保留(11200030006000.125+0.001)。toFixed(5)=(11200030006000.125+0.001)。toFixed(5)所以这个数字是四舍五入的。这仍然是一个奇怪的问题,你必须对小数点进行假设。仍然在寻找一个准确的解决方案,我不必担心ParseFloat(11200030006000.126)仍然有11200030006000.127
var arr = [1234563995.721, 12345691212.718, 1234568421.5891, 12345677093.49284];
var sum = 0;
for( var i = 0; i < arr.length; i++ ) {
sum += arr[i];
}
alert( "fMath(sum) = " + Math.round( sum * 1e12 ) / 1e12 );
alert( "fFixed(sum) = " + sum.toFixed( 5 ) );