Возможный дубликат:
Математика JavaScript не работает?
Почему JS испортил эту простую математику?
console.log(.1 + .2) // 0.3000000000000004
console.log(.3 + .6) // 0.8999999999999999
Возможный дубликат:
Математика JavaScript не работает?
Почему JS испортил эту простую математику?
console.log(.1 + .2) // 0.3000000000000004
console.log(.3 + .6) // 0.8999999999999999
Это не проблема JS, а более общий компьютер. Плавающее число не может правильно хранить все десятичные числа, поскольку они хранят данные в двоичном формате Например:
0.5 is store as b0.1
but 0.1 = 1/10 so it 1/16 + (1/10-1/16) = 1/16 + 0.0375
0.0375 = 1/32 + (0.0375-1/32) = 1/32 + 00625 ... etc
so in binary 0.1 is 0.00011...
но это бесконечно. За исключением того, что компьютер должен остановиться в какой-то момент. Поэтому, если в нашем примере мы остановимся на 0,00011, то вместо 0.1. 0.09375.
Во всяком случае, дело в том, что это не зависит от языка, а от компьютера. В зависимости от языка, как вы показываете числа. Обычно число раундов языка соответствует приемлемому представлению. По-видимому, JS этого не делает.
Итак, что вам нужно сделать (число в памяти достаточно точное) - это просто сказать JS, чтобы округлить "красиво" число при преобразовании их в текст.
Вы можете попробовать функцию sprintf
, которая дает вам прекрасный контроль над отображением числа.
Из руководства с плавающей точкой:
Почему мои числа, такие как 0,1 + 0,2, не складываются в хороший раунд 0,3, а вместо этого я получаю странный результат, такой как 0,30000000000000004?
Поскольку внутренне, компьютеры используют формат (двоичная с плавающей точкой), который не может точно представить число как 0,1, 0,2 или 0,3 вообще.
Когда код компилируется или интерпретируется, ваш "0.1" уже округляется до ближайшего числа в этом формате, что приводит к небольшой ошибке округления даже до того, как произойдет вычисление.
На сайте есть подробные объяснения, а также информация о том, как решить проблему (и как решить, является ли это проблемой вообще в вашем случае).
Это не ограничение только на javascript, оно применяется ко всем вычислениям с плавающей запятой. Проблема в том, что 0,1 и 0,2 и 0,3 точно не представляются в виде флагов javascript (или C или Java и т.д.). Таким образом, результат, который вы видите, обусловлен этой неточностями.
В частности, точно определенные суммы степеней двух функций точно представлены. 0.5 = = 0.1b = 2 ^ (- 1), 0.25 = 0.01b = (2 ^ -2), 0.75 = 0.11b = (2 ^ -1 + 2 ^ -2) - все в порядке. Но 1/10 = 0.000110001100011..b может быть выражен только в виде бесконечной суммы степеней 2, которую язык отбрасывает в какой-то момент. Его это измельчение, которое вызывает эти незначительные ошибки.
Это нормально для всех языков программирования, потому что не все десятичные значения могут быть представлены точно в двоичном формате. См. Что каждый компьютерный ученый должен знать о арифметике с плавающей точкой
Это связано с тем, как компьютеры обрабатывают плавающие числа. Подробнее об этом можно прочитать здесь: http://docs.sun.com/source/806-3568/ncg_goldberg.html