Как округлить число в Javascript?


159

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

  • 192,168 => 192,20
  • 192,11 => 192,20
  • 192,21 => 192,30
  • 192,26 => 192,30
  • 192,20 => 192,20

Как этого добиться с помощью Javascript? Встроенная функция Javascript округляет число на основе стандартной логики (меньше и больше, чем 5, чтобы округлить).

Ответы:


313
/**
 * @param num The number to round
 * @param precision The number of decimal places to preserve
 */
function roundUp(num, precision) {
  precision = Math.pow(10, precision)
  return Math.ceil(num * precision) / precision
}

roundUp(192.168, 1) //=> 192.2

2
@AndrewMarshall, какова цель умножения, а затем деления на 10?
codecowboy

6
@codecowboy Если вы этого не сделаете, то ceil()передадим вам 193, поэтому мы должны убедиться, что вся точность, которую мы хотим сохранить, должна быть выше десятичной точки. Затем мы выполняем обратную операцию, чтобы восстановить «исходное» значение.
Эндрю Маршалл

1
Если вы 192.19999999999997.toFixed(1)num
наберете

4
А для тех, кто интересуется, как округлить до ближайшего целого числа, вам просто нужен Math.ceil (). Остальное - просто десятичные дроби. Чтобы сэкономить время другим, мне понадобилось время, чтобы добраться до этого!
Найджел Б. Пек

Это решение имеет ошибку: Math.ceil (0.0159 * 1000000000) / точность. Вы получите фракцию 0,015900001. Нужно добавить валидацию диапазона для точности.
Франк

26

Немного поздно, но, может создать повторно используемую функцию javascript для этой цели:

// Arguments: number to round, number of decimal places
function roundNumber(rnum, rlength) { 
    var newnumber = Math.round(rnum * Math.pow(10, rlength)) / Math.pow(10, rlength);
    return newnumber;
}

Вызовите функцию как

alert(roundNumber(192.168,2));

2
Это прекрасно работает, но ОП спросил, как округлить число, поэтому здесь нужно использовать Math.ceil вместо Math.round.
kloddant

Этот ответ лучше, чем принятый, если вы хотите правильно округлить, несмотря на то, к какому десятичному знаку вы стремитесь. Пример: 1.054 -> 1.05 1.055 -> 1.06 ОДНАКО здесь крайний случай: 1.005 -> 1 1.006 -> 1.01 И 1.015 -> 1.01 1.016 -> 1.02 Так что будьте осторожны.
Джей К

21

Обычное округление будет работать с небольшой настройкой:

Math.round(price * 10)/10

и если вы хотите сохранить формат валюты, вы можете использовать метод Number .toFixed()

(Math.round(price * 10)/10).toFixed(2)

Хотя это сделает это String =)


Math.round (192.11 * 100) / 100 -> 192.11
krtek

1
Второму не нужно округлять, это больше похоже наprice.toFixed(2)
Майкл Крелин - хакер

@Krtek упс, спасибо, что поймали это. Я неправильно прочитал вопрос. Ответ обновлен.
Шад

2
ОП спросил, как округлить число, поэтому здесь вместо Math.round следует использовать Math.ceil.
Клоддант


2

ОП ожидает две вещи:
A. округлить до десятых и
Б. показать ноль на сотом месте (типичная потребность в валюте).

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

//Arguments: number to round, number of decimal places.

function roundPrice(rnum, rlength) {
    var newnumber = Math.ceil(rnum * Math.pow(10, rlength-1)) / Math.pow(10, rlength-1);
    var toTenths = newnumber.toFixed(rlength);
    return toTenths;
}

alert(roundPrice(678.91011,2)); // returns 679.00
alert(roundPrice(876.54321,2)); // returns 876.60

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

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

function roundNumber(rnum, rlength) { 
    var newnumber = Math.round(rnum * Math.pow(10, rlength)) / Math.pow(10, rlength);
    return newnumber;
}

alert(roundNumber(678.91011,2)); // returns 678.91

function ceilNumber(rnum, rlength) { 
    var newnumber = Math.ceil(rnum * Math.pow(10, rlength)) / Math.pow(10, rlength);
    return newnumber;
}

alert(ceilNumber(678.91011,2)); // returns 678.92

2

Хорошо, на этот вопрос уже получен ответ, но я подумал, что вам может понравиться мой ответ, который вызывает функцию math.pow () один раз. Я думаю, мне нравится хранить вещи СУХОЙ.

function roundIt(num, precision) {
    var rounder = Math.pow(10, precision);
    return (Math.round(num * rounder) / rounder).toFixed(precision)
};

Это как бы складывает все вместе. Замените Math.round () на Math.ceil () для округления вместо округления, чего и хотел ОП.


1

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

function limitDecimal(num,decimal){
     return num.toString().substring(0, num.toString().indexOf('.')) + (num.toString().substr(num.toString().indexOf('.'), decimal+1));
}

В качестве более короткой альтернативы: return ('' + num) .split ('.'). Shift ()
Роберто

спасибо Роберто, этот код работает, но удаляет все десятичные дроби
Behnam Mohammadi

0

Я давно использую ответ @AndrewMarshall, но обнаружил некоторые крайние случаи. Следующие тесты не проходят:

equals(roundUp(9.69545, 4), 9.6955);
equals(roundUp(37.760000000000005, 4), 37.76);
equals(roundUp(5.83333333, 4), 5.8333);

Вот что я сейчас использую для правильного поведения:

// Closure
(function() {
  /**
   * Decimal adjustment of a number.
   *
   * @param {String}  type  The type of adjustment.
   * @param {Number}  value The number.
   * @param {Integer} exp   The exponent (the 10 logarithm of the adjustment base).
   * @returns {Number} The adjusted value.
   */
  function decimalAdjust(type, value, exp) {
    // If the exp is undefined or zero...
    if (typeof exp === 'undefined' || +exp === 0) {
      return Math[type](value);
    }
    value = +value;
    exp = +exp;
    // If the value is not a number or the exp is not an integer...
    if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0)) {
      return NaN;
    }
    // If the value is negative...
    if (value < 0) {
      return -decimalAdjust(type, -value, exp);
    }
    // Shift
    value = value.toString().split('e');
    value = Math[type](+(value[0] + 'e' + (value[1] ? (+value[1] - exp) : -exp)));
    // Shift back
    value = value.toString().split('e');
    return +(value[0] + 'e' + (value[1] ? (+value[1] + exp) : exp));
  }

  // Decimal round
  if (!Math.round10) {
    Math.round10 = function(value, exp) {
      return decimalAdjust('round', value, exp);
    };
  }
  // Decimal floor
  if (!Math.floor10) {
    Math.floor10 = function(value, exp) {
      return decimalAdjust('floor', value, exp);
    };
  }
  // Decimal ceil
  if (!Math.ceil10) {
    Math.ceil10 = function(value, exp) {
      return decimalAdjust('ceil', value, exp);
    };
  }
})();

// Round
Math.round10(55.55, -1);   // 55.6
Math.round10(55.549, -1);  // 55.5
Math.round10(55, 1);       // 60
Math.round10(54.9, 1);     // 50
Math.round10(-55.55, -1);  // -55.5
Math.round10(-55.551, -1); // -55.6
Math.round10(-55, 1);      // -50
Math.round10(-55.1, 1);    // -60
Math.round10(1.005, -2);   // 1.01 -- compare this with Math.round(1.005*100)/100 above
Math.round10(-1.005, -2);  // -1.01
// Floor
Math.floor10(55.59, -1);   // 55.5
Math.floor10(59, 1);       // 50
Math.floor10(-55.51, -1);  // -55.6
Math.floor10(-51, 1);      // -60
// Ceil
Math.ceil10(55.51, -1);    // 55.6
Math.ceil10(51, 1);        // 60
Math.ceil10(-55.59, -1);   // -55.5
Math.ceil10(-59, 1);       // -50

Источник: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round


1
Ваши тесты кажутся неверными. roundUp(37.760000000000005, 4)должно быть 37.7601и roundUp(5.83333333, 4)должно быть 5.8334. Эти два (и ваш первый) все верны для предоставленного мною fn.
Эндрю Маршалл

У @AndrewMarshall есть причина, ваши ожидаемые значения неверны для случаев 2 и 3.
Амн

-3

parseInt всегда округляет су .....

console.log(parseInt(5.8)+1);

do parseInt () + 1

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