Формат номера, чтобы всегда показывать 2 десятичных знака

783

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

Примеры:

number     display
------     -------
1          1.00
1.341      1.34
1.345      1.35

Я использовал это:

parseFloat(num).toFixed(2);

Но это отображается 1как 1, а не 1.00.

Varada
источник
2
Я имею в виду, что если я введу 1, он не будет показывать число как 1,00, но если я введу 1,345, то он покажет 1,35
Варада
1
Я перефразировал твой вопрос тем, что, как мне кажется, ты искал. Пожалуйста, убедитесь, что я вас правильно понял.
друид
Точное округление с поддержкой. gist.github.com/ArminVieweg/28647e735aa6efaba401
TarranJones

Ответы:

1118
(Math.round(num * 100) / 100).toFixed(2);

Live Demo

Обратите внимание, что он округляется до 2 десятичных знаков, поэтому входные данные 1.346вернутся 1.35.

выполнять тяжелую работу
источник
6
@Kooilnc: OP хочет 1отображать как 1.00и 1.341отображать как 1.34.
Drudge
49
Нет необходимости использовать round (), поскольку toFixed () округляет его.
Милан Бабушков
27
toFixed () делает это вокруг, но не забывайте, что он возвращает строку ... Так что этот метод действительно полезен только для отображения. Если вы хотите выполнить дальнейшие математические вычисления для округленного значения, не используйте toFixed ().
TWright
8
Согласно MDN, Math.round не всегда дает точные результаты из-за ошибок округления. Я проверил это с 1,005, который должен округляться до 1,01, но это дает 1,00. Используйте мой ответ для постоянной точности: stackoverflow.com/a/34796988/3549440 .
конец
13
Весь этот ответ может быть уменьшен до (+num).toFixed(2). Он даже сохраняет ошибку округления в оригинале, см . Ответ Нейта .
RobG
322
Number(1).toFixed(2);         // 1.00
Number(1.341).toFixed(2);     // 1.34
Number(1.345).toFixed(2);     // 1.34 NOTE: See andy's comment below.
Number(1.3450001).toFixed(2); // 1.35

Абель АНЕЙРОС
источник
1
Последняя строка неверна. Я попробовал это в консоли Chrome и `` Number (1.365) .toFixed (2) возвращает "1.37"
Andre
1
@Andre, Chrome 29.0.1547.57 дает мне 1.34для выражения Number(1.345).toFixed(2).
Дрю Ноакс
1
toFixed выполняет округление, которое вы можете увидеть почти на каждом тестовом номере.
Энди
40
Случайно представленный последний комментарий перед завершением .. 1.345является примером числа, которое не может быть сохранено точно с плавающей запятой, поэтому я думаю, что причина, по которой он не округляется, как вы ожидаете, заключается в том, что он на самом деле хранится как число немного менее 1,345, и он округляется вниз. Если вы протестируете вместо этого, (1.34500001).toFixed(2)тогда вы увидите, что все правильно округляется до1.35
andy
94

Этот ответ не удастся, если value = 1.005.

Как лучшее решение можно избежать проблемы округления, используя числа, представленные в экспоненциальной записи:

Number(Math.round(1.005+'e2')+'e-2'); // 1.01

Более чистый код, предложенный @Kon и первоначальным автором:

Number(Math.round(parseFloat(value + 'e' + decimalPlaces)) + 'e-' + decimalPlaces)

Вы можете добавить toFixed()в конце, чтобы сохранить десятичную точку, например: 1.00но обратите внимание, что она вернется в виде строки.

Number(Math.round(parseFloat(value + 'e' + decimalPlaces)) + 'e-' + decimalPlaces).toFixed(decimalPlaces)

Кредит: округление десятичных дробей в JavaScript

razu
источник
13
Удивительно, что все остальные здесь не смогли увидеть, что toFixedесть такая проблема округления. Ваш ответ должен быть принятым.
Армфут
1
Просто проверил, было ли это все еще так. Вы по-прежнему правы для Chrome версии 59.0.3071.115. Ваше решение округляется до 1,005 (1,01) и округляется до 1,00499999 (1,00)
Artistan
jsfiddle.net/Artistan/qq895bnp/28 есть «времена», когда toFixed будет работать, но это довольно противоречиво. :)
Artistan
Объемный номер в parseFloat является его возвращаемой строкой
user889030
1
Это твердый ответ. Я могу подумать о нескольких улучшениях: (1) VS Code (файл TypeScript) не любит, когда Math.round () передается в виде строки. (2) Сделать количество десятичных знаков динамическим (не жестко запрограммированным в 2). (3) toFixed () кажется ненужным. Итак, что я придумалаNumber(Math.round(parseFloat(value + 'e' + decimalPlaces)) + 'e-' + decimalPlaces)
Кон
23
var num = new Number(14.12);
console.log(num.toPrecision(2));//outputs 14
console.log(num.toPrecision(3));//outputs 14.1
console.log(num.toPrecision(4));//outputs 14.12
console.log(num.toPrecision(5));//outputs 14.120
Тибериу Петку
источник
Это дает неожиданные результаты, если ваше число может быть 1,4, 23,654 и 0, какую точность вы бы взяли?
Shinzou
2
Обратите внимание, что OP запрашивает «округление, где это применимо» . toPrecisionтолько форматирует число к определенному числу десятичных знаков, просто пропуская лишние места, но не округляя их . Конечно, это тоже может быть очень полезно, но важно понимать разницу.
Вооз - Восстановить Монику
1
На самом деле toPrecision делает круглые, по словам Mozilla. Тест:(20.55).toPrecision(3) "20.6"
Джеймс Л.
2
Если вы хотите удалить конечные нули , приведите их к числу или числу с плавающей запятой после использования toFixed: const formattedVal = Number(val.toFixed(2));не используйте toPrecision, так как при использовании точного параметра он учитывает недесятичные числа.
Джеймс Л.
17

Для наиболее точного округления создайте эту функцию:

function round(value, decimals) {
    return Number(Math.round(value +'e'+ decimals) +'e-'+ decimals).toFixed(decimals);
}

и используйте его для округления до 2 десятичных знаков:

console.log("seeked to " + round(1.005, 2));
> 1.01

Спасибо Razu , этой статье и справке Math.round от MDN .

Nate
источник
1
как насчет 1.0049999999999998934?
4esn0k
1
Это не выходит за пределы 2 дп
Стивен Аделакун
1
jsfiddle.net/Artistan/qq895bnp протестирован, это единственный последовательный метод, который я видел. Спасибо.
Артист
17

Для современных браузеров используйте toLocaleString:

var num = 1.345;
num.toLocaleString(undefined, { maximumFractionDigits: 2, minimumFractionDigits: 2 });

Укажите тег локали в качестве первого параметра для управления десятичным разделителем . Для точки используйте, например, английский язык США:

num.toLocaleString("en-US", { maximumFractionDigits: 2, minimumFractionDigits: 2 });

который дает:

1,35

В большинстве стран Европы в качестве десятичного разделителя используется запятая, поэтому, если вы, например, используете шведский / шведский язык:

num.toLocaleString("sv-SE", { maximumFractionDigits: 2, minimumFractionDigits: 2 });

это даст:

1.35

holmis83
источник
Не уверен, почему за это проголосовали, мне показалось, что это хорошо работает. Пожалуйста, добавьте комментарий, если вы намереваетесь понизить голос, если что-то не так с этим!
Джон Кульвинер
13

Самый простой ответ:

var num = 1.2353453;
num.toFixed(2); // 1.24

Пример: http://jsfiddle.net/E2XU7/

macio.Jun
источник
11
Ну, toFixedуже было предложено в stackoverflow.com/a/13292833/218196 . Какую дополнительную информацию предоставляет ваш вопрос?
Феликс Клинг
этот ответ не включает в себя круглую функциональность, мой ответ включает в себя tho.
macio.Jun
8
Э - э? Это точно такой же ответ. Звонок toFixedна номер.
Феликс Клинг
1
Правильно, та же функция, но результат этого ответа вводит в заблуждение, я просто исправил это, выразив круглую функциональность.
macio.Jun
Вопрос гласит: «... округление, где это применимо». Ваш ответ не предполагает округления.
Крис
12

Гораздо более общее решение для округления до N мест

function roundN(num,n){
  return parseFloat(Math.round(num * Math.pow(10, n)) /Math.pow(10,n)).toFixed(n);
}


console.log(roundN(1,2))
console.log(roundN(1.34,2))
console.log(roundN(1.35,2))
console.log(roundN(1.344,2))
console.log(roundN(1.345,2))
console.log(roundN(1.344,3))
console.log(roundN(1.345,3))
console.log(roundN(1.3444,3))
console.log(roundN(1.3455,3))

Output

1.00
1.34
1.35
1.34
1.35
1.344
1.345
1.344
1.346
PirateApp
источник
1
Это также не удается с определенными числами, близкими к 0, roundN(-3.4028230607370965e+38,2)возвращается "-3.4028230607370965e+38"вместо ожидаемых 0,00
Ferrybig
интересно @ Ferrybig я протестирую упомянутые вами числа и подумаю об
обходном
1
Обратите внимание, что вышеупомянутое число не должно показывать ноль, а вместо этого огромное число, это была просто ошибка в моем мозгу. Но это все еще не работает, так как это все еще не показывает 2 десятичных
знака
9

Если вы уже используете jQuery, вы можете посмотреть на использование числового формата jQuery плагина .

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

$.number( 123, 2 ); // Returns '123.00'

Вы также можете получить jQuery Number Format от GitHub .

Сэм Шенерт
источник
11
Излишне использовать плагин «просто иметь десятичную часть фиксированной длины».
Lashae
9
@Lashae, конечно, если это все, что ты хочешь сделать. Я разместил это на тот случай, если ОП или кому-то еще понадобится дополнительная функциональность, предоставляемая плагином.
Сэм Сехнерт
если бы
автор
7

Это то, что вы имеете в виду?

function showAsFloat(num, n){
      return !isNaN(+num) ? (+num).toFixed(n || 2) : num;
}

document.querySelector('#result').textContent = 
    [
     'command                      | result',
     '-----------------------------------------------',
     'showAsFloat(1);              | ' + showAsFloat(1),
     'showAsFloat(1.314);          | ' + showAsFloat(1.314),
     'showAsFloat(\'notanumber\')    | ' + showAsFloat('notanumber'),
     'showAsFloat(\'23.44567\', 3)   | ' + showAsFloat('23.44567', 3),
     'showAsFloat(2456198, 5)      | ' + showAsFloat('2456198', 5),
     'showAsFloat(0);              | ' + showAsFloat(0)
    ].join('\n');
<pre id="result"></pre>

KooiInc
источник
6

Преобразуйте число в строку, сохранив только два десятичных знака:

var num = 5.56789;
var n = num.toFixed(2);

Результат n будет:

5.57
Бехнам Мохаммади
источник
4

Вы ищете пол?

var num = 1.42482;
var num2 = 1;
var fnum = Math.floor(num).toFixed(2);
var fnum2 = Math.floor(num2).toFixed(2);
alert(fnum + " and " + fnum2); //both values will be 1.00
Samwise
источник
4
Я не думаю, что он хочет округлить до ближайшего целого числа.
Drudge
да, я не был уверен из описания, но я просто выкинул его туда, в
случайном порядке
3
function currencyFormat (num) {
    return "$" + num.toFixed(2).replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1,")
}

console.info(currencyFormat(2665));   // $2,665.00
console.info(currencyFormat(102665)); // $102,665.00
Ар Нет
источник
3

Вот также универсальная функция, которая может форматировать любое количество десятичных знаков:

function numberFormat(val, decimalPlaces) {

    var multiplier = Math.pow(10, decimalPlaces);
    return (Math.round(val * multiplier) / multiplier).toFixed(decimalPlaces);
}
Минас Мина
источник
3

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

Подробное объяснение округления и форматирования здесь: http://www.merlyn.demon.co.uk/js-round.htm#RiJ

Как правило, округление и форматирование должны выполняться только как последний шаг перед выводом. Это может привести к неожиданно большим ошибкам и разрушению форматирования.

RobG
источник
Временами я покачал головой по собственному выбору, чтобы в последнее время так глубоко погрузиться во всю эту платформу JS / Ecma. :( «Там, где требуется определенное форматирование, вы должны написать свою собственную подпрограмму или использовать библиотечную функцию, которая делает то, что вам нужно. Базовых функциональных возможностей ECMAScript обычно недостаточно для отображения отформатированных чисел. но потому что этот факт существует. Просто грустно. Встань, Javascript! :)
ChrisH
2

function number_format(string,decimals=2,decimal=',',thousands='.',pre='R$ ',pos=' Reais'){
  var numbers = string.toString().match(/\d+/g).join([]);
  numbers = numbers.padStart(decimals+1, "0");
  var splitNumbers = numbers.split("").reverse();
  var mask = '';
  splitNumbers.forEach(function(d,i){
    if (i == decimals) { mask = decimal + mask; }
    if (i>(decimals+1) && ((i-2)%(decimals+1))==0) { mask = thousands + mask; }
    mask = d + mask;
  });
  return pre + mask + pos;
}
var element = document.getElementById("format");
var money= number_format("10987654321",2,',','.');
element.innerHTML = money;
#format{
display:inline-block;
padding:10px;
border:1px solid #ddd;
background:#f5f5f5;
}
<div id='format'>Test 123456789</div>

Леонардо Филипе
источник
2

Просто наткнитесь на этот самый длинный поток, ниже мое решение:

parseFloat(Math.round((parseFloat(num * 100)).toFixed(2)) / 100 ).toFixed(2)

Дайте мне знать, если кто-нибудь может проткнуть дыру

Сэм Джонсон
источник
2

Этешам Ахмад Надим
источник
2
Этого куска кода достаточно, чтобы удовлетворить ваши требования parseFloat(num.toFixed(2))
ква
1

Вы не даете нам полную картину.

javascript:alert(parseFloat(1).toFixed(2))показывает 1,00 в моих браузерах, когда я вставляю его в строку адреса. Однако, если вы сделаете что-то с этим потом, оно вернется.

var num = 2
document.getElementById('spanId').innerHTML=(parseFloat(num).toFixed(2)-1)


shows 1 and not 1.00
mplungjan
источник
Работает в FF 50, Chrome 49 и IE 8
Флориан Штрауб
1
var quantity = 12;

var import1 = 12.55;

var total = quantity * import1;

var answer = parseFloat(total).toFixed(2);

document.write(answer);
Даршак Шехда
источник
1

Мне пришлось выбирать между преобразованиями parseFloat () и Number (), прежде чем я смог сделать вызов toFixed (). Вот пример форматирования чисел после захвата пользовательского ввода.

HTML:

<input type="number" class="dec-number" min="0" step="0.01" />

Обработчик события:

$('.dec-number').on('change', function () {
     const value = $(this).val();
     $(this).val(value.toFixed(2));
});

Приведенный выше код приведет к исключению TypeError. Обратите внимание, что хотя тип ввода html - «число», пользовательский ввод - это тип данных «строка». Однако функция toFixed () может быть вызвана только для объекта, который является Number.

Мой окончательный код будет выглядеть следующим образом:

$('.dec-number').on('change', function () {
     const value = Number($(this).val());
     $(this).val(value.toFixed(2));
});

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

Витек
источник
0

Я люблю:

var num = 12.749;
parseFloat((Math.round(num * 100) / 100).toFixed(2)); // 123.75

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

Юичи
источник
Я предполагаю, что если цель состояла в том, чтобы отображать с точностью до 2 десятичных разрядов, синтаксический анализ float с этим не справится. НапримерparseFloat("1.00") // 1
Стейн де Витт
0

Расширить объект Math с помощью точного метода

Object.defineProperty(Math, 'precision',{
   value: function (value,precision,type){
             var v = parseFloat(value),
                 p = Math.max(precision,0)||0,
                 t = type||'round';
              return (Math[t](v*Math.pow(10,p))/Math.pow(10,p)).toFixed(p);
          }
    });

console.log(
    Math.precision(3.1,3), // round 3 digits 
    Math.precision(0.12345,2,'ceil'), // ceil 2 digits
    Math.precision(1.1) // integer part
)

bortunac
источник
0

parseInt(number * 100) / 100; работал на меня.

Будь здоров, Пандей
источник
0

Вот еще одно решение для округления только с использованием минимального значения, то есть убедитесь, что рассчитанная сумма не будет больше исходной суммы (иногда необходимой для транзакций):

Math.floor(num* 100 )/100;
Naty
источник
0

Вы можете попробовать этот код:

    function FormatNumber(number, numberOfDigits = 2) {
        try {
            return new Intl.NumberFormat('en-US').format(parseFloat(number).toFixed(2));
        } catch (error) {
            return 0;
        }
    }

    var test1 = FormatNumber('1000000.4444');
    alert(test1); // 1,000,000.44

    var test2 = FormatNumber(100000000000.55555555, 4);
    alert(test2); // 100,000,000,000.56
VnDevil
источник
0

Попробуйте код ниже:

function numberWithCommas(number) { 

   var newval = parseFloat(Math.round(number * 100) / 100).toFixed(2);

   return newval.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
}
Цуна Савада
источник
-3
(num + "").replace(/^([0-9]*)(\.[0-9]{1,2})?.*$/,"$1$2")
Суп ворона
источник
-3

Вот как я решаю свою проблему:

parseFloat(parseFloat(floatString).toFixed(2));
Алекс Т.
источник