可能的重复:
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 会表现出这样的行为?
可能的重复:
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 会表现出这样的行为?
因为浮点并不完全精确。您最终可能会出现细微的差异。
(旁注:我认为您的意思是var x = .6 - .5;
否则,您正在与 比较-0.1
。0.1
)
JavaScript 使用IEEE-754双精度 64 位浮点 ( ref )。这是浮点数的一个非常好的近似值,但是没有完美的方法可以用二进制表示所有浮点数。
有些差异比其他差异更容易看到。例如:
console.log(0.1 + 0.2); // "0.30000000000000004"
有一些 JavaScript 库可以做“十进制”的事情,比如 C# 的decimal
类型或 Java 的BigDecimal
. 这就是数字实际存储为一系列十进制数字的地方。但它们不是灵丹妙药,它们只是有不同类别的问题(1 / 3
例如,尝试用它准确表示)。“十进制”类型/库非常适合金融应用程序,因为我们习惯于处理金融事物中所需的舍入风格,但代价是它们往往比 IEEE 浮点数慢。
让我们输出你的x
和y
值:
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
以相同数量的位置运行,最终应该是相同的数字(即使这个数字并不完全准确)。