0

可能的重复:
JavaScript 的数学被破坏了吗?

认为,

var x = .6 - .5;

var y = 10.2 – 10.1;

var z = .2  -  .1;

比较结果

x == y;     // false

x == .1;    // false

y == .1;    // false

z == .1;    // true

为什么 Javascript 会表现出这样的行为?

4

1 回答 1

6

因为浮点并不完全精确。您最终可能会出现细微的差异。

(旁注:我认为您的意思是var x = .6 - .5;否则,您正在与 比较-0.10.1

JavaScript 使用IEEE-754双精度 64 位浮点 ( ref )。这是浮点数的一个非常好的近似值,但是没有完美的方法可以用二进制表示所有浮点数。

有些差异比其他差异更容易看到。例如:

console.log(0.1 + 0.2); // "0.30000000000000004"

有一些 JavaScript 库可以做“十进制”的事情,比如 C# 的decimal类型或 Java 的BigDecimal. 这就是数字实际存储为一系列十进制数字的地方。但它们不是灵丹妙药,它们只是有不同类别的问题(1 / 3例如,尝试用它准确表示)。“十进制”类型/库非常适合金融应用程序,因为我们习惯于处理金融事物中所需的舍入风格,但代价是它们往往比 IEEE 浮点数慢。

让我们输出你的xy值:

var x = .6 - .5;
console.log(x); // "0.09999999999999998"

var y = 10.2 - 10.1;
console.log(y); // "0.09999999999999964"

没有什么大惊小怪0.09999999999999998的。:-)!=0.09999999999999964

您可以将这些合理化以进行比较:

function roundTwoPlaces(num) {
  return Math.round(num * 100) / 100;
}

var x = roundTwoPlaces(0.6 - 0.5);

var y = roundTwoPlaces(10.2 - 10.1);

console.log(x);       // "0.1"
console.log(y);       // "0.1"
console.log(x === y); // "true"

或者更通用的解决方案:

function round(num, places) {
    var mult = Math.pow(10, places);
    return Math.round(num * mult) / mult;
}

实例| 资源

请注意,准确率仍然可能出现在结果数字中,但至少有两个彼此非常、非常、非常接近的数字,如果round以相同数量的位置运行,最终应该是相同的数字(即使这个数字并不完全准确)。

于 2012-05-12T09:16:56.453 回答