Javascript:四舍五入的数字不相加(33.3 + 33.3 + 33.3 = 99.89999999999999

Javascript: Rounded numbers don't add up (33.3 + 33.3 + 33.3 = 99.89999999999999?)

本文关键字:89999999999999 四舍五入 数字 Javascript      更新时间:2023-09-26

考虑这个 javascript,它四舍五入到最接近的十分之一,然后将数字相加。

var log = function(key, value) {
  var li = document.createElement("li");
  li.appendChild(document.createTextNode(key + " = " + value)); 
  document.getElementById("results").appendChild(li); 
  };
var number1 = Math.round(10*33.333)/10; // gives 33.3
var number2 = Math.round(10*33.333)/10; // gives 33.3
var number3 = Math.round(10*33.333)/10; // gives 33.3
var totalOfAllNumbers = number1 + number2 + number3; //gives 99.89999999999999?
var totalOfAllRealNumbers = 33.3 + 33.3 + 33.3; //gives 99.9?
log("number1", number1);
log("number2", number2);
log("number3", number3);
log("totalOfAllNumbers", totalOfAllNumbers);
<ul id="results"></ul>

这些数字似乎是四舍五入的,但总数加起来不是 99.9?为什么?

手动输入为 33.3 的数字与除法结果有什么区别?它们是不同的类型吗?

我讨厌给出轻率的回应,但它给出了舍入错误号"因为JavaScript"。

一个稍微不那么轻率的答案是,引擎试图在加法的每一步猜测(如 ECMA 规范所述)类型,并且在类型猜测算法的某个地方,它会猜测它是双精度而不是浮点数(反之亦然),这就是你看到这种类型的精度损失的时候。如果数值准确性对你来说至关重要,我建议使用不同的编程语言,具有更合理、更可预测的数字类型。

编辑:

例如,考虑python 2.7:

>>> a = round(10*33.333, 2)/10
>>> b = round(10*33.333, 2)/10
>>> c = round(10*33.333, 2)/10
>>> a + b + c
99.999

或红宝石:

2.1.2 :001 > a = (10*33.333).round(2)/10
 => 33.333
2.1.2 :002 > b = (10*33.333).round(2)/10
 => 33.333
2.1.2 :003 > c = (10*33.333).round(2)/10
 => 33.333
2.1.2 :004 > a + b + c
 => 99.999