Як округлити число в 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
flamer.ohr

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,05 -> 1,06, ЯКЩО ось кращий регістр: 1.005 -> 1 1.006 -> 1,01 І 1,015 -> 1,01 1,016 -> 1,02 Тож будьте обережні.
Jay K

21

Звичайне округлення буде працювати з невеликим твіст:

Math.round(price * 10)/10

і якщо ви хочете зберегти формат валюти, ви можете скористатися методом Число .toFixed()

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

Хоча це зробить це рядком =)


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

1
Другий не потребує округлення, він більше схожий наprice.toFixed(2)
Майкл Крелін - хакер

@Krtek ooops, Дякую, що це зрозумів. Я неправильно прочитав питання. Відповідь оновлено.
Шад

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


2

ОП розраховує на дві речі:
А. обернеться до вищих десятих, а
Б. покаже нуль на сотому місці (типова потреба у валюті).

Виконання обох вимог, мабуть, потребує окремого методу для кожного з перерахованих вище. Ось підхід, який ґрунтується на запропонованій відповіді suryakiran:

//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 ('' + число) .split ('.'). Shift ()
Роберто

спасибі Роберто за цей код працює, але видаліть усі
десятки

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.
Amn

-3

синтаксичний розбір завжди кругляє су .....

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

зробіть розбір () + 1

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.