当总和超过两个时,Javascript中的舍入数字会失败吗?

当总和超过两个时,Javascript中的舍入数字会失败吗?,javascript,numbers,rounding,Javascript,Numbers,Rounding,我知道我肯定遗漏了什么,我试图将任意数量的数字四舍五入到两位小数,但没有成功 var sumOne = 0; var sumTwo = 0; [12.993, 12.99, 12.99].forEach(function(number){ sumOne += roundOne(number * 0.1); sumTwo += roundTwo(number * 0.1); }) function roundOne(n){ return (Math.round((n *100

我知道我肯定遗漏了什么,我试图将任意数量的数字四舍五入到两位小数,但没有成功

var sumOne = 0;
var sumTwo = 0;
[12.993, 12.99, 12.99].forEach(function(number){
    sumOne += roundOne(number * 0.1);
    sumTwo += roundTwo(number * 0.1);
})

function roundOne(n){
  return (Math.round((n *100))/100);
}
function roundTwo(n){
    return +(n.toFixed(2));
}
console.log("sumOne is ", sumOne, " sumTwo is ", sumTwo);
在上面的JSFIDLE或代码中,我得到以下输出

sumOne is  3.9000000000000004  sumTwo is  3.9000000000000004
为什么这两种四舍五入方法都不能得到只有两位小数的和

奇怪的是,如果我尝试使用数组中只有两个数字的相同代码,我的结果与预期的一样,这两种方法的和只有两个小数位

var sumOne = 0;
var sumTwo = 0;
[12.993, 12.99, 12.99].forEach(function(number){

  sumTwo += roundTwo(number); // dont *0.1
})

function roundOne(n){
  return (Math.round((n *100))/100);
}
function roundTwo(n){
    return +(n.toFixed(2));
}
console.log("sumOne is ", sumOne, " sumTwo is ", sumTwo);
我已经删除了roundTwonumber*0.1,这使得sumTwo是正确的

我不知道你为什么这么做

现在是将每个数字分别四舍五入并进行汇总。我认为这是理想的效果


如果你想把他们聚集起来。然后在执行toFixed2之前添加0.05。如果你想四舍五入减去0.05,这将对结果进行四舍五入,然后将结果清除到小数点后两位。

这是浮点精度的问题。最简单的解决方案:

console.logsumOne是,sumOne.toFixed2,sumtow2是,sumtow2.toFixed2


您还可以将数字乘以1000,使其成为整数,对其进行数学运算,然后再除以1000。

您遇到了一些浮点舍入错误。这并不罕见。如果绝对需要避免使用整数类型,请强制变量使用整数类型。roundOne函数有多余的括号:return Math.roundn*100/100;行。名称似乎也不合适,因为它四舍五入到小数点后两位。另请参见:顺便提一下,为什么在添加数字之前要将数字四舍五入?只是等待和取整最终结果不是更常见吗?用乘法和除法来模拟固定不是一个好主意。使用因子1000与使用因子100存在相同的问题,请参见舍入应留到最后,因为舍入误差会累积,并且可能不一致,具体取决于操作顺序。@RobG-但230*100/100是否返回230?答案是先乘后除。虽然很明显,根据计算结果,您可能仍然会得到小数点,我同意将舍入保留到最后。@nnnnnn-我想如果输入总是一个只有两个小数点的字符串,并且没有一个算术生成分数,那么*100/100可以工作,但它不是一个通用的解决方案。