假设,
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会显示这种行为?
答案 0 :(得分:6)
因为浮点不是很精确。您最终可能会遇到轻微的差异。
(旁注:我认为您的意思是var x = .6 - .5;
否则,您要将-0.1
与0.1
进行比较。)
JavaScript使用IEEE-754双精度64位浮点(ref)。这是浮点数的非常好的近似值,但没有完美的方法来表示二进制中的所有浮点数。
有些差异比其他差异更容易看到。例如:
console.log(0.1 + 0.2); // "0.30000000000000004"
有一些JavaScript库可以执行“十进制”事件a'la 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
具有相同位数的情况下运行,则至少两个非常非常非常接近的数字仍然可能存在于结果数中,最终应该是相同的数字(即使这个数字不完全准确)。