Поскольку не все числа могут быть точно представлены с плавающей запятой (JavaScript использует числа IEEE 754 с 64-разрядным форматом двойной точности), возникают ошибки округления. Например:
alert(0.1 + 0.2); // "0.30000000000000004"
Эта проблема существует во всех системах нумерации с ограниченным хранилищем (например, во всех системах нумерации), но мы с вами привыкли иметь дело с нашей десятичной системой (которая не может точно представлять «одну треть») и поэтому некоторые удивляются различных значений, которые форматы с плавающей запятой, используемые компьютерами, не могут точно представить. Именно из-за этого вы видите все больше и больше «десятичных» типов стилей (в Java BigDecimal
, в C # decimal
и т. Д.), Которые используют наш стиль представления чисел (по цене) и это полезно для приложений, где округление должно более точно соответствовать нашим ожиданиям (например, финансовые приложения).
Обновление : я не пробовал, но вы можете обойти это, немного изменив значения, прежде чем захватывать их строки. Например, это работает с вашим конкретным примером ( живая копия ):
Код:
function display(msg) {
var p = document.createElement('p');
p.innerHTML = msg;
document.body.appendChild(p);
}
function preciseToString(num) {
var floored = Math.floor(num),
fraction = num - floored,
rv,
fractionString,
n;
rv = String(floored);
n = rv.indexOf(".");
if (n >= 0) {
rv = rv.substring(0, n);
}
fractionString = String(fraction);
if (fractionString.substring(0, 2) !== "0.") {
return String(num); // punt
}
rv += "." + fractionString.substring(2);
return rv;
}
display(preciseToString(10000000000000.126));
Результат:
10000000000000.126953125
... которые затем, конечно, можно обрезать по своему усмотрению. Конечно, важно отметить, что 10000000000000.126953125 != 10000000000000.126
. Но я думаю, что корабль уже проплыл (например, Number
уже содержал неточное значение), учитывая, что вы видели .127
. Я не вижу, чтобы вы знали, что оригинал был только в трех местах, а не с Number
.
Я не говорю, что вышеизложенное является в любом случае надежным, вы должны действительно пройти через это, чтобы доказать это (то есть, я ) не делать что-то сутулое там. И опять же, поскольку вы не знаете, где именно закончилась точность, я не уверен, насколько она полезна.