Как я могу округлить число в JavaScript? .toFixed () возвращает строку? - PullRequest
136 голосов
/ 17 февраля 2010

Я что-то здесь упускаю?

var someNumber = 123.456;
someNumber = someNumber.toFixed(2);
alert(typeof(someNumber));
//alerts string

Почему возвращает .toFixed() строку?

Я хочу округлить число до 2 десятичных цифр.

Ответы [ 11 ]

130 голосов
/ 07 апреля 2015

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";

Однако имейте в виду, что загрязнение прототипа считается плохим при написании модуля, поскольку у модулей не должно быть никаких побочных эффектов.

107 голосов
/ 17 февраля 2010

Возвращает строку, потому что 0,1 и ее степени (которые используются для отображения десятичных дробей) не представимы (по крайней мере, не с полной точностью) в двоичных системах с плавающей запятой.

Например, 0,1 действительно 0,1000000000000000055511151231257827021181583404541015625, а 0,01 действительно 0,01000000000000000020816681711721685132943093776702880859375. (Спасибо BigDecimal за доказательство моей точки. :-P)

Поэтому (при отсутствии десятичного числа с плавающей запятой или типа рациональных чисел) вывод его в виде строки - единственный способ обрезать его с точностью, необходимой для отображения.

105 голосов
/ 20 февраля 2013

Я решил эту проблему, изменив это:

someNumber = someNumber.toFixed(2)

... на это:

someNumber = +someNumber.toFixed(2);

Однако это преобразует число в строку и анализирует его снова, что существенно повлияет на производительность. Если вы заботитесь о производительности или безопасности типов, проверьте и другие ответы.

23 голосов
/ 26 февраля 2016

Почему бы не использовать parseFloat?

var someNumber = 123.456;
someNumber = parseFloat(someNumber.toFixed(2));
alert(typeof(someNumber));
//alerts number
12 голосов
/ 17 февраля 2010

Конечно, он возвращает строку. Если вы хотите округлить числовую переменную, вы бы использовали вместо этого Math.round (). Смысл toFixed состоит в том, чтобы отформатировать число с фиксированным количеством десятичных знаков для отображения пользователю .

11 голосов
/ 29 декабря 2014

Я решил это путем преобразования его обратно в число с помощью функции Number() JavaScript

var x = 2.2873424;
x = Number(x.toFixed(2));
3 голосов
/ 18 января 2018

Вы можете просто использовать '+', чтобы преобразовать результат в число.

var x = 22.032423;
x = +x.toFixed(2); // x = 22.03
3 голосов
/ 17 февраля 2010

Что вы ожидаете, что он вернется, когда он должен отформатировать число? Если у вас есть число, вы ничего не можете с ним сделать, потому что, например, 2 == 2.0 == 2.00 и т. Д., Так что это должна быть строка.

1 голос
/ 28 июня 2018

Вот несколько более функциональный вариант ответа 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
1 голос
/ 17 февраля 2010

Потому что его основное использование - отображение чисел? Если вы хотите округлить числа, используйте Math.round() с соответствующими коэффициентами.

...