Поскольку плавающая точка не является абсолютно точной. Вы можете получить минус отличия.
(Примечание стороны: Я думаю, что вы имели в виду var x = .6 - .5;
В противном случае, вы сравниваете -0.1
с 0.1
.)
JavaScript использует IEEE-754 двойной точности 64-бит с плавающей точкой (ref). Это чрезвычайно хорошее приближение чисел с плавающей запятой, но нет идеального способа представления всех чисел с плавающей запятой в двоичном формате.
Некоторые несоответствия легче увидеть, чем другие. Например:
console.log(0.1 + 0.2); // "0.30000000000000004"
Есть некоторые библиотеки JavaScript там, которые делают «десятичный» вещь a'la С # 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;
}
Live example | source
Обратите внимание, что в полученном числе может быть погрешность точности, но по крайней мере два числа, которые очень, очень, очень близки друг к другу, если они проходят через round
с таким же количеством мест, должны заканчиваться (даже если это число не совсем точно).
Ваши первые два сравнения немного странны. Почему вы ожидаете, что они совпадут? (-0.1 vs 0.1) – Mat
Связано с: http://stackoverflow.com/questions/1458633/elegant-workaround-for-javascript-floating-point-number-problem – BasTaller