JavaScript-математика, округление до двух знаков после запятой

У меня есть синтаксис ниже JavaScript:

var discount = Math.round(100 - (price / listprice) * 100);

Это округляет до целого числа, как я могу вернуть результат с двумя десятичными знаками?

Ответ 1

ПРИМЕЧАНИЕ. - См. Редактирование 4, если важна 3-значная точность.

var discount = (price / listprice).toFixed(2);

toFixed округляется вверх или вниз для вас в зависимости от значений, превышающих 2 десятичных знака.

Пример: http://jsfiddle.net/calder12/tv9HY/

Документация: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed

Изменить. Как упоминалось другими, это преобразует результат в строку. Чтобы избежать этого:

var discount = +((price / listprice).toFixed(2));

Изменить 2. Как уже упоминалось в комментариях, эта функция не выполняется с некоторой точностью, например, в случае 1.005 она вернет 1,00 вместо 1.01. Если точность до такой степени важна, я нашел этот ответ: fooobar.com/questions/14417/... Кажется, что это хорошо работает со всеми те испытаниями, которые я пробовал.

Требуется одна незначительная модификация, но функция в ответе, указанном выше, возвращает целые числа, когда она округляется до одной, поэтому, например, 99.004 вернет 99 вместо 99.00, что не идеально подходит для отображения цен.

Изменить 3. Кажется, что toFixed на фактическом возврате был STILL, набирая некоторые цифры, это окончательное редактирование, похоже, работает. Geez так много репараций!

   var discount = roundTo((price / listprice), 2);

   function roundTo(n, digits) {
     if (digits === undefined) {
       digits = 0;
     }

     var multiplicator = Math.pow(10, digits);
     n = parseFloat((n * multiplicator).toFixed(11));
     var test =(Math.round(n) / multiplicator);
     return +(test.toFixed(digits));
   }

См. здесь пример скрипта: https://jsfiddle.net/calder12/3Lbhfy5s/

Редактировать 4. Вы, ребята, меня убиваете. Edit 3 терпит неудачу на отрицательных числах, не копаясь в том, почему это просто проще справиться с превращением отрицательного числа положительным, прежде чем делать округление, а затем вернуть его обратно, прежде чем возвращать результат.

function roundTo(n, digits) {
    var negative = false;
    if (digits === undefined) {
        digits = 0;
    }
        if( n < 0) {
        negative = true;
      n = n * -1;
    }
    var multiplicator = Math.pow(10, digits);
    n = parseFloat((n * multiplicator).toFixed(11));
    n = (Math.round(n) / multiplicator).toFixed(2);
    if( negative ) {    
        n = (n * -1).toFixed(2);
    }
    return n;
}

Fiddle: https://jsfiddle.net/3Lbhfy5s/79/

Ответ 2

Если вы используете унарный плюс для преобразования строки в число как описано в MDN.

Например: +discount.toFixed(2)

Ответ 3

Функции Math.round() и .toFixed() предназначены для округления до ближайшего целого числа, и вы можете получить некоторые нежелательные ошибки при работе с десятичными знаками и использовать метод "multiply and divide" для Math.round() или параметр для .toFixed(). Например, если вы попытаетесь округлить 1.005, используя Math.round(1.005 * 100)/100, тогда вы получите результат 1 и 1.00 с использованием .toFixed(2) вместо получения правильного ответа 1.01.

Вы можете использовать следующие действия для решения этой проблемы:

Number(Math.round(100 - (price / listprice) * 100 + 'e2') + 'e-2');

Добавьте .toFixed(2), чтобы получить два десятичных знака, которые вы хотели.

Number(Math.round(100 - (price / listprice) * 100 + 'e2') + 'e-2').toFixed(2);

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

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

Пример: https://jsfiddle.net/k5tpq3pd/36/

Alternativ

Вы можете добавить круглую функцию к номеру с использованием прототипа. Я бы не предложил добавить здесь .toFixed() здесь, поскольку он вернет строку вместо числа.

Number.prototype.round = function(decimals) {
    return Number((Math.round(this + "e" + decimals)  + "e-" + decimals));
}

и используйте его следующим образом:

var numberToRound = 100 - (price / listprice) * 100;
numberToRound.round(2);
numberToRound.round(2).toFixed(2); //Converts it to string with two decimals

Пример https://jsfiddle.net/k5tpq3pd/35/

Источник: http://www.jacklmoore.com/notes/rounding-in-javascript/

Ответ 4

Чтобы получить результат с двумя десятичными знаками, вы можете сделать следующее:

var discount = Math.round((100 - (price / listprice) * 100) * 100) / 100;

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

Ответ 5

попробуйте использовать discount.toFixed(2);

Ответ 6

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

var discount = + ((price / listprice).toFixed(2));

Отредактировано: Я только что обнаружил, что кажется ошибкой в ​​Firefox 35.0.1, что означает, что приведенное выше может дать NaN некоторые значения.
Я изменил свой код на

var discount = Math.round(price / listprice * 100) / 100;

Это дает число с двумя знаками после запятой. Если вы хотите три, вы умножаете и делите на 1000 и т.д.
OP хочет два десятичных разряда всегда, но если toFixed() нарушено в Firefox, сначала нужно зафиксировать его.
См. https://bugzilla.mozilla.org/show_bug.cgi?id=1134388

Ответ 7

Самый быстрый способ - быстрее, чем toFixed():

ДВЕ ДЕКЛАМЫ

x      = .123456
result = Math.round(x * 100) / 100  // result .12

ТРИ ДЕЦИМАЛЬНОСТИ

x      = .123456
result = Math.round(x * 1000) / 1000      // result .123

Ответ 8

Самое лучшее и простое решение, которое я нашел, -

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

round(1.005, 2); // 1.01

Ссылка: http://www.jacklmoore.com/notes/rounding-in-javascript/

Ответ 9

Я думаю, что лучший способ, который я видел, это умножить на 10 на количество цифр, затем сделать Math.round, а затем, наконец, делить на 10 на количество цифр. Вот простая функция, которую я использую в typescript:

function roundToXDigits(value: number, digits: number) {
    value = value * Math.pow(10, digits);
    value = Math.round(value);
    value = value / Math.pow(10, digits);
    return value;
}

Или простой javascript:

function roundToXDigits(value, digits) {
    if(!digits){
        digits = 2;
    }
    value = value * Math.pow(10, digits);
    value = Math.round(value);
    value = value / Math.pow(10, digits);
    return value;
}

Ответ 10

    function round(num,dec)
    {
      num = Math.round(num+'e'+dec)
      return Number(num+'e-'+dec)
    }
      //Round to a decimal of your choosing:
    round(1.3453,2)

Ответ 11

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



    var testNum = 134.9567654;
    var decPl = 2;
    var testRes = roundDec(testNum,decPl);  
    alert (testNum + ' rounded to ' + decPl + ' decimal places is ' + testRes);

    function roundDec(nbr,dec_places){
        var mult = Math.pow(10,dec_places);
        return Math.round(nbr * mult) / mult;
    }

Ответ 12

function discoverOriginalPrice(discountedPrice, salePercentage) {
  var originalPrice = discountedPrice / (1 - (salePercentage * .01));
  return +originalPrice.toFixed(2);
}

Ответ 13

Вот рабочий пример

var value=200.2365455;
result=Math.round(value*100)/100    //result will be 200.24