Javascript toFixed() 方法中的舍入

Rounding in Javascript toFixed() method

我知道toFixed()方法在javascript中将数字转换为字符串,保留指定的小数位数,就像下面的代码, 设置小数点后的位数为 2 .

我的问题是:必要时是否四舍五入。如下面的代码所示,我将转换数字:0.075。我认为四舍五入 0.075 应该是 0.08,因为“5 上升”。但是,在下面的第一种情况下看起来很奇怪。所以我很困惑。

var a=0.25*0.3;
var res1 = a.toFixed(2);
console.log(res1);
//Output: a is 0.07 (Is there something wrong?)

var b=0.025*3;
var res2= b.toFixed(2);
console.log(res2);
//Output:b is 0.08

我知道使用 Math.js 可以解决问题。但是,我只是想知道问题的原因?是toFixed()方法的问题还是javascript.

中数据类型的问题

the docs 所述,toFixed() 在必要时进行 舍入。舍入行为是在数字的 -.5 < x <= +.5 范围内舍入。

您观察到的奇怪行为与上面链接的文档中的说明一致:

Floating point numbers cannot represent all decimals precisely in binary which can lead to unexpected results such as 0.1 + 0.2 === 0.3 returning false .

换句话说,这是典型的浮点精度损失案例 - 几乎在任何语言中都会遇到的问题。如果你观察 ab 的完整输出,你会看到 a == 0.075b == 0.07500000000000001 由于浮点精度 - 因此给定这些值它与定义舍入行为以将 a 舍入到 .07 并将 b 舍入到 .08.

您遇到的问题不是 JavaScript 特有的,它在一般计算中很常见。

这两个算术计算的结果相同 – 0.075:

  • 0.25 * 0.3 = 0.075
  • 0.025 * 3 = 0.075

这是使用常用的十进制数制。

然而,计算机的核心不是使用十进制,而是二进制——一切都基于 0 和 1。

正因为如此,他们实际上很难把上面的计算正确。 JavaScript 和其他编程语言必须近似结果,给你这个:

  • 0.25 * 0.3 = 0.75
  • 0.025 * 3 = 0.07500000000000001

您现在可以了解为什么 toFixed returns 不同的结果:

  • 0.75.toFixed(2) = 0.07
  • 0.07500000000000001.toFixed(2) = 0.08