Округление до ближайшего 0,05 в JavaScript

Вопрос
Кто-нибудь знает способ округления поплавка до ближайшего 0,05 в JavaScript?

Пример

BEFORE | AFTER
  2.51 | 2.55
  2.50 | 2.50
  2.56 | 2.60

Текущий код

var _ceil = Math.ceil;
Math.ceil = function(number, decimals){
    if (arguments.length == 1)
    return _ceil(number);

    multiplier = Math.pow(10, decimals);
    return _ceil(number * multiplier) / multiplier;
}

Тогда в другом месте... return (Math.ceil((amount - 0.05), 1) + 0.05).toFixed(2);

Что приводит к...

BEFORE | AFTER
  2.51 | 2.55
  2.50 | 2.55
  2.56 | 2.65

Ответ 1

Умножьте на 20, затем разделите на 20:

(Math.ceil(number*20)/20).toFixed(2)

Ответ 2

Роб ответит с моим дополнением:

(Math.ceil(number*20 - 0.5)/20).toFixed(2)

В противном случае он всегда округляется до ближайшего 0,05.

** ОБНОВЛЕНИЕ **

Извините, было отмечено, что это не то, что хотел автор оригинала.

Ответ 3

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

var val = 26.14,
    factor = 0.05;

val = Math.round(val / factor) * factor;

Это будет работать для десятков, сотен или любого числа. Если вы специально округляете число выше, используйте Math.ceil вместо Math.round.

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

Number(Number(1.5454545).toFixed(1));

Он создает строку с фиксированным числом, а затем превращает ее в реальную Number.

Ответ 4

Я бы написал функцию, которая делает это для вас

  • переместите десятичное число в два места (умножьте на 100)
  • тогда mod (%), что inflatedNumber на 5 и получим остаток
  • вычесть remainder из 5, чтобы вы знали, что "пробел" (ceilGap) находится между вашим номером и ближайшим ближайшим .05
  • наконец, разделите ваш inflatedNumber на 100, чтобы он возвращался к исходному поплавку, и voila, ваше число будет округлено до ближайшего .05.

    function calcNearestPointZeroFive(num){
        var inflatedNumber = num*100,
            remainder     = inflatedNumber % 5;
            ceilGap       = 5 - remainder
    
        return (inflatedNumber + ceilGap)/100
    }
    

Если вы хотите оставить номера, например, 5.50 нетронутыми, вы всегда можете добавить эту шашку:

if (remainder===0){
    return num
} else {
    var ceilGap  = 5 - remainder
    return (inflatedNumber + ceilGap)/100
}

Ответ 5

Вам нужно положить -1 в круглую половину и после этого умножить на -1, как пример ниже.

<script type="text/javascript">

  function roundNumber(number, precision, isDown) {
    var factor = Math.pow(10, precision);
    var tempNumber = number * factor;
    var roundedTempNumber = 0;
    if (isDown) {
      tempNumber = -tempNumber;
      roundedTempNumber = Math.round(tempNumber) * -1;
    } else {
      roundedTempNumber = Math.round(tempNumber);
    }
    return roundedTempNumber / factor;
  }
</script>

<div class="col-sm-12">
  <p>Round number 1.25 down: <script>document.write(roundNumber(1.25, 1, true));</script>
  </p>
  <p>Round number 1.25 up: <script>document.write(roundNumber(1.25, 1, false));</script></p>
</div>

Ответ 6

Я успешно использовал эту функцию в своем проекте:

roundToNearestFiveCents( number: any ) {
    return parseFloat((Math.round(number / 0.05) * 0.05).toFixed(2));
}

Может быть полезным для тех, кто хочет просто округлить до 5 центов по своим денежным результатам, сохраняет результат в виде числа, поэтому, если вы добавите его дополнительно, это не приведет к конкатенации строк; также не излишне округлять, как указано в нескольких других ответах. Также ограничивается двумя десятичными знаками, что обычно для финансов.

Ответ 7

Мое решение и тест:

let round = function(number, precision = 2, rounding = 0.05) {
  let multiply = 1 / rounding;

  return parseFloat((Math.round(number * multiply) / multiply)).toFixed(precision);
};

https://jsfiddle.net/maciejSzewczyk/7r1tvhdk/40/