JavaScript: округлить до числа десятичных знаков, но удалить лишние нули


85

Вот сценарий: я получаю, .9999999999999999когда должен 1.0.
Я могу позволить себе потерять десятичный знак точности, поэтому я использую .toFixed(15), какие работы.

Округление работает, но проблема в том, что мне дали 1.000000000000000.
Есть ли способ округлить до числа десятичных знаков, но убрать лишние пробелы?

Примечание: .toPrecisionэто не то, что я хочу; Я только хочу указать, сколько чисел после десятичной точки.
Примечание 2: я не могу просто использовать, .toPrecision(1)потому что мне нужно поддерживать высокую точность для чисел, которые на самом деле имеют данные после десятичной точки. В идеале должно быть столько десятичных знаков, сколько необходимо (до 15).


Дело в том, что .toFixed возвращает String, поэтому простое обращение к нему через Number, а затем обратно к String приведет к его повторному преобразованию без конечных нулей.
Neil

@ Натан: просто для пояснения. Вы просто хотите удалить завершающие нули в строке , полученной с помощью toFixed ()?
Jiri Kriz

Ответы:


141
>>> parseFloat(0.9999999.toFixed(4));
1
>>> parseFloat(0.0009999999.toFixed(4));
0.001
>>> parseFloat(0.0000009999999.toFixed(4));
0

4
Не забывайте заключать их в круглые скобки, когда обрабатываете отрицательные числа: -2.34.toFixed(1)возвращает -2.3из-за приоритета оператора .
Константин Ван

1
Использование унарного оператора + должно быть быстрее, чем parseFloatфункция: +number.toFixed(13)это выражение также можно использовать для удаления неточностей в числах JavaScript, например, 1.0000000000000045.
ygoe


19

Насколько я понимаю, вы хотите удалить завершающие нули в строке, которую вы получили через toFixed(). Это чистая строковая операция:

var x = 1.1230000;
var y = x.toFixed(15).replace(/0+$/, "");  // ==> 1.123

6
Вы единственный, кто действительно ответил на вопрос .. спасибо!
Mugen

4
Это оставляет точку на круглых числах ("100.00" => "100.")
pckill

5
@pckill, если вы не хотите, чтобы точка была заменена, вы можете включить ее в регулярное выражение ( ...replace(/\.?0+$/, "");).
Зак Сноу

Это не удается при 0 и -0, потому что 0становится пустой строкой ""и -0становится -, ни то, ни другое не ожидается (предположительно). @ zach-snow ваше предложенное решение также не работает на 0 и -0.
robocat

@Mugen, в чем проблема с ответом Гаса?
trysis

9

Number(n.toFixed(15)) or +(n.toFixed(15)) преобразует десятичную строку из 15 знаков в число, удаляя конечные нули.


1
Подумал, что я укажу на это, + (n.toFixed (...)) намного эффективнее, чем parseFloat. Не уверен, почему, но он также более эффективен, чем Number в Chrome.
Domino

8

Если вы приведете возвращаемое значение к числу, эти конечные нули будут отброшены. Это также менее многословно, чем parseFloat()есть.

+(4.55555).toFixed(2);
//-> 4.56

+(4).toFixed(2);
//-> 4

При этом используется унарный оператор + , так что если использовать это как часть операции строки вам необходимо иметь инфикс + перед ним: var n=0.9999999999999999; console.log('output ' + +n.toFixed(2));. К вашему сведению, унарный + перед строкой преобразует ее в число. Из MDN: Unary + может:

преобразовывать строковые представления целых чисел и чисел с плавающей запятой, а также нестроковые значения true, false и null. Поддерживаются целые числа как в десятичном, так и в шестнадцатеричном (с префиксом "0x") форматах. Поддерживаются отрицательные числа (но не шестнадцатеричные). Если он не может проанализировать конкретное значение, он будет оценивать как NaN.


@robocat Я только что сделал простую проверку; +(4.1).toFixed(4)находится 4.1в Chrome 60 .
Константин Ван

Я не понимаю. По какой причине этот ответ был отклонен?
Константин Ван

@K Вы были правы, поэтому я удалил свой предыдущий комментарий и добавил к ответу (я думаю, что использовал infix + со строкой на lhs, а не правильно использовал unary +. Обычно я более осторожен! Ура)
robocat

Этот ответ по-прежнему работает с NaN, Infinity, -Infinity, 3e30 и 0. Некоторые другие ответы терпят неудачу в некоторых угловых случаях.
robocat

(4) .toFixed (2) -> «4.00» в Chrome 60.0.3112.113
Даниэль Ку

1

Ни один из них не дал мне то, что я искал, исходя из заголовка вопроса, который, например, был для 5.00 равным 5 и 5.10 для 5.1. Мое решение было таким:

num.toFixed(places).replace(/\.?0+$/, '')

'5.00'.replace(/\.?0+$/, '') // 5
'5.10'.replace(/\.?0+$/, '') // 5.1
'5.0000001'.replace(/\.?0+$/, '') // 5.0000001
'5.0001000'.replace(/\.?0+$/, '') // 5.0001

Примечание. Регулярное выражение работает, только если places > 0

PS https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed


Не работает 5e30(меняет номер на 5e3). Угловые шкафы дьявольски!
robocat

0

Есть лучший метод, который сохраняет точность, а также удаляет нули. Для этого нужно ввести число, и с помощью некоторой магии кастинга удаляются любые конечные нули. Я обнаружил, что 16 - это предел точности для меня, что неплохо, если вы не будете помещать спутник на плутон.

function convertToFixed(inputnum)
{

      var mynum = inputnum.toPrecision(16);
//If you have a string already ignore this first line and change mynum.toString to the inputnum

      var mynumstr = mynum.toString();
    return parseFloat(mynumstr);
    }
    alert(convertToFixed(6.6/6));

0

toFixed()Метод форматирует с numberиспользованием нотации с фиксированной точкой, и возвращает string.

Он применяет стратегию округления до половины .

(0.124).toFixed(2); // returns 0.12
(0.125).toFixed(2); // returns 0.13

Как вы описали, это действительно также иногда приводит к (потенциально ненужным) конечным нулям.

(0.001).toFixed(2); // returns 0.00

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

+(0.001).toFixed(2); // the shortest

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.