Я что-то пропустил?
var someNumber = 123.456;
someNumber = someNumber.toFixed(2);
alert(typeof(someNumber));
//alerts string
Почему возвращает .toFixed()
строку?
Я хочу округлить число до двух десятичных цифр.
Я что-то пропустил?
var someNumber = 123.456;
someNumber = someNumber.toFixed(2);
alert(typeof(someNumber));
//alerts string
Почему возвращает .toFixed()
строку?
Я хочу округлить число до двух десятичных цифр.
Он возвращает строку, потому что 0,1 и ее полномочия (которые используются для отображения десятичных дробей) не могут быть представлены (по крайней мере, не с полной точностью) в двоичных системах с плавающей запятой.
Например, 0,1 действительно составляет 0,1000000000000000055511151231257827021181583404541015625, а 0,01 действительно 0,01000000000000000020816681711721685132943093776702880859375. (Благодаря BigDecimal
для доказательства моей точки.: -P)
Поэтому (без десятичной плавающей запятой или рациональным типом числа), выводя его в виде строки - это единственный способ получить ее подстроенную до точности, необходимой для отображения.
Number.prototype.toFixed
- это функция, предназначенная для форматирования числа перед его печатью. Он из семьи toString
, toExponential
и toPrecision
.
Чтобы округлить число, вы должны сделать это:
someNumber = 42.008;
someNumber = Math.round( someNumber * 1e2 ) / 1e2;
someNumber === 42.01;
// if you need 3 digits, replace 1e2 with 1e3 etc.
.
Или, если вам нужна нативная функция, вы можете расширить прототип:
Number.prototype.toFixedNumber = function(x, base){
var pow = Math.pow(base||10,x);
return Math.round(this*pow) / pow;
}
someNumber = 42.008;
someNumber = someNumber.toFixedNumber(2);
someNumber === 42.01;
//or even hexadecimal
someNumber = 0xAF309/256 //which is af3.09
someNumber = someNumber.toFixedNumber(1, 16);
someNumber.toString(16) === "af3.1";
Однако имейте в виду, что загрязнение прототипа считается плохим при написании модуля, поскольку модули не должны иметь побочных эффектов.
Я решил эту проблему, изменив это:
someNumber = someNumber.toFixed(2)
...к этому:
someNumber = +someNumber.toFixed(2);
Однако это преобразует число в строку и анализирует его снова, что окажет значительное влияние на производительность. Если вы заботитесь о производительности или безопасности типов, проверьте и другие ответы.
Почему бы не использовать parseFloat
?
var someNumber = 123.456;
someNumber = parseFloat(someNumber.toFixed(2));
alert(typeof(someNumber));
//alerts number
Конечно, он возвращает строку. Если вы хотите округлить числовую переменную, вы должны использовать Math.round(). Точка toFixed предназначена для форматирования числа с фиксированным числом десятичных знаков для отображения пользователю.
Я решил его преобразовать обратно в число с помощью функции JavaScript Number()
var x = 2.2873424;
x = Number(x.toFixed(2));
Что бы вы ожидали, что он вернется, когда он должен отформатировать номер? Если у вас есть номер, вы вряд ли можете что-либо сделать с ним, например, 2 == 2.0 == 2.00
и т.д., Поэтому он должен быть строкой.
Вы можете просто использовать "+", чтобы преобразовать результат в число.
var x = 22.032423;
x = +x.toFixed(2); // x = 22.03
Чтобы привести пример того, почему это должна быть строка:
Если вы отформатируете 1.toFixed(2), вы получите "1,00".
Это не то же самое, что 1, поскольку 1 не имеет 2 десятичных знаков.
Я знаю, что JavaScript не совсем язык производительности, но есть вероятность, что вы получите лучшую производительность для округления, если вы используете что-то вроде: roundedValue = Math.round(value * 100) * 0.01
Потому что его основное использование - отображение номеров? Если вы хотите округлить числа, используйте Math.round()
с соответствующими факторами.
Здесь чуть более функциональный вариант ответа m93a
предоставлен.
const toFixedNumber = (toFixTo = 2, base = 10) => num => {
const pow = Math.pow(base, toFixTo)
return +(Math.round(num * pow) / pow)
}
const oneNumber = 10.12323223
const result1 = toFixedNumber(2)(oneNumber) // 10.12
const result2 = toFixedNumber(3)(oneNumber) // 10.123
// or using pipeline-operator
const result3 = oneNumber |> toFixedNumber(2) // 10.12
console.log(parseFloat(12.233333.toFixed(2)));