Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/docker/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
JavaScript添加十进制数问题_Javascript_Numbers - Fatal编程技术网

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
@GGG
Math.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 ) );