Як округлити плаваючі числа у javascript?


298

Мені потрібно круглий, наприклад , 6.688689до 6.7, але він завжди показує мені 7.

Мій метод:

Math.round(6.688689);
//or
Math.round(6.688689, 1);
//or 
Math.round(6.688689, 2);

Але результат завжди однаковий 7... Що я роблю неправильно?


28
(6.688689​).toFixed(1);
Shadow Wizard is Ear for You

Перевірте це
raina77ow

можливий дублікат круглого числа в JavaScript до N десяткових знаків - будь ласка, використовуйте пошук, перш ніж задавати нове запитання.
Фелікс Клінг


1
@ShadowWizard правильний. Однак .toFixedповертає рядок. Обов’язково заверніть результат Number(). Див. Прийняту відповідь та інші.
Йордан Арсено

Відповіді:


534
Number((6.688689).toFixed(1)); // 6.7

22
Перетворити число в рядок, а потім знову повернутися? Це не може бути швидким.
csl

Не добре, якщо ваш номер має менше десяткових знаків, ніж потрібно. Він додає деякі
njzk2

2
як показують еталони JS, це повільніше, ніж метод
@fivedigit

13
Number((456.1235).toFixed(3)) -> 456.123, Number((1.235).toFixed(2)) -> 1.24... Дурний Javasript ...
NoOne

6
Це може НЕ робити те, що ви очікуєте! Результат може залежати навіть від браузера, дивіться це запитання: stackoverflow.com/q/566564/2224996
травень

199
var number = 6.688689;
var roundedNumber = Math.round(number * 10) / 10;

13
Це не завжди працює. Візьмемо Math.round(1.005*100)/100для прикладу MDN
tybro0103

7
@ tybro0103 Зло з плаваючою точкою: 1.005 * 100 = 100.49999999999999(принаймні, в двигуні JS, який я намагався). Ось чому це не працює, і чому ви ніколи не повинні покладатися на те, що поплавці будуть абсолютно точними.
судо

1
Неправильно. Math.round (1,015 * 100) / 100 повертає 1,01 замість 1,02
Марко Марсала

81

Використовуйте toFixed()функцію.

(6.688689).toFixed(); // equal to 7
(6.688689).toFixed(1); // equal to 6.7
(6.688689).toFixed(2); // equal to 6.69

5
Це може НЕ робити те, що ви очікуєте! Результат може залежати навіть від браузера, дивіться це запитання: stackoverflow.com/q/566564/2224996
травень

9
(6.688689) .toFixed (); дорівнює "7", а не 7. Те ж саме для інших прикладів.
Вадо

35

Оновлено (2019-10). Завдяки коду Reece Daniels, який доступний нижче, доступний як набір функцій, упакованих у очікуваний раунд npm-пакет (подивіться).


Ви можете використовувати хелперну функцію з прикладу MDN . Чим ви будете мати більшу гнучкість:

Math.round10(5.25, 0);  // 5
Math.round10(5.25, -1); // 5.3
Math.round10(5.25, -2); // 5.25
Math.round10(5, 0);     // 5
Math.round10(5, -1);    // 5
Math.round10(5, -2);    // 5

Оновлено (15.01.2019). Здається, що в документах MDN більше немає цих допоміжних функцій. Ось резервна копія з прикладами:

// 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

2
?? "Math.round10 - це не функція"
Пітер Краус

1
Я вважаю це надзвичайно корисним, тому збило його у пакеті швидких npm для тих, хто хоче його використовувати без здуття додаткового коду. Записано @aspanchenko з оригінальною відповіддю також: npmjs.com/package/expected-round
Reece Daniels

19
> +(6.688687).toPrecision(2)
6.7

NumberОб'єкт в JavaScript є метод , який робить саме те , що вам потрібно. Цей метод є Number.toPrecision([precision]).

Так само, як і з .toFixed(1)ним, перетворює результат у рядок, і його потрібно перетворити назад у число. Тут використано +префікс.

простий орієнтир на моєму ноутбуці:

number = 25.645234 typeof number
50000000 x number.toFixed(1) = 25.6 typeof string / 17527ms
50000000 x +(number.toFixed(1)) = 25.6 typeof number / 23764ms
50000000 x number.toPrecision(3) = 25.6 typeof string / 10100ms
50000000 x +(number.toPrecision(3)) = 25.6 typeof number / 18492ms
50000000 x Math.round(number*10)/10 = 25.6 typeof number / 58ms
string = 25.645234 typeof string
50000000 x Math.round(string*10)/10 = 25.6 typeof number / 7109ms

На мою думку, це найкраща відповідь (найкраща з точки зору найкращої практики, найпростіший підхід).
cezar

1
1e-10.toPrecision(3): "1.00e-10" - це округлення до значущих цифр .
Всеволод Голованов

9

Якщо ви не тільки хочете використовувати, toFixed()але ceil()і floor()на поплавці, тоді ви можете скористатись такою функцією:

function roundUsing(func, number, prec) {
    var tempnumber = number * Math.pow(10, prec);
    tempnumber = func(tempnumber);
    return tempnumber / Math.pow(10, prec);
}

Виробляє:

> roundUsing(Math.floor, 0.99999999, 3)
0.999
> roundUsing(Math.ceil, 0.1111111, 3)
0.112

UPD:

Інший можливий спосіб:

Number.prototype.roundUsing = function(func, prec){
    var temp = this * Math.pow(10, prec)
    temp = func(temp);
    return temp / Math.pow(10, prec)
}

Виробляє:

> 6.688689.roundUsing(Math.ceil, 1)
6.7
> 6.688689.roundUsing(Math.round, 1)
6.7
> 6.688689.roundUsing(Math.floor, 1)
6.6

як ми тоді вирішуємо, коли використовувати стелю, підлогу чи круглу для округлення? Наприклад: roundUsing (Math.round, 1.015, 2) roundUsing (Math.ceil, 1.015, 2) дають 2 різні значення Як ми можемо знати, який з них використовувати
gaurav5430

7

Моя розширена кругла функція:

function round(value, precision) {
  if (Number.isInteger(precision)) {
    var shift = Math.pow(10, precision);
    // Limited preventing decimal issue
    return (Math.round( value * shift + 0.00000000000001 ) / shift);
  } else {
    return Math.round(value);
  }
} 

Приклад Вихід:

round(123.688689)     // 123
round(123.688689, 0)  // 123
round(123.688689, 1)  // 123.7
round(123.688689, 2)  // 123.69
round(123.688689, -2) // 100
round(1.015, 2) // 1.02

1
це схоже на відповідь @ Fivedigit. раунд (1.015, 2) все одно дає 1,01 замість 1,02
gaurav5430

@ gaurav5430, дякую за ваш звіт, я це виправив.
Нік Цай

6

Дивись нижче

var original = 28.59;

var result=Math.round(original*10)/10 поверне вам повернення 28.6

Сподіваюся, що це ви хочете ..


7
"Якби я мав десять разів, коли я бачив, як хтось використовує FLOAT для зберігання валюти, я мав би 999,997634 доларів", - Білл Карвін.
emix

2
Неправильно. Math.round (1.015 * 100) / 100
Марко Марсала

3
float(value,ndec);
function float(num,x){
this.num=num;
this.x=x;
var p=Math.pow(10,this.x);
return (Math.round((this.num).toFixed(this.x)*p))/p;
}

2

Я думаю, що ця функція може допомогти.

 function round(value, ndec){
    var n = 10;
    for(var i = 1; i < ndec; i++){
        n *=10;
    }

    if(!ndec || ndec <= 0)
        return Math.round(value);
    else
        return Math.round(value * n) / n;
}


round(2.245, 2) //2.25
round(2.245, 0) //2

подібно до деяких інших відповідей, це не вдається до раунду (1.015, 2), який повинен дати 1,02
gaurav5430

1

Я думаю, що нижче функція може допомогти

function roundOff(value,round) {
   return (parseInt(value * (10 ** (round + 1))) - parseInt(value * (10 ** round)) * 10) > 4 ? (((parseFloat(parseInt((value + parseFloat(1 / (10 ** round))) * (10 ** round))))) / (10 ** round)) : (parseFloat(parseInt(value * (10 ** round))) / ( 10 ** round));
}

використання: roundOff(600.23458,2);повернеться600.23


Чи можете ви пояснити, що додає ця відповідь, що раніше не була охоплена попередніми відповідями?
stealththeninja

подібно до деяких інших відповідей, це не вдається до раунду (1.015, 2), який повинен дати 1,02
gaurav5430

1

якщо ви знаходитесь у контексті node.js, ви можете спробувати mathjs

const math = require('mathjs')
math.round(3.1415926, 2) 
// result: 3.14

1

Існує альтернатива .toLocaleString () форматування чисел, з великою кількістю варіантів щодо локалів, групування, формування валюти, нотацій. Деякі приклади:

Округніть до 1 десяткової точки, поверніть поплавок:

const n = +6.688689.toLocaleString('fullwide', {maximumFractionDigits:1})
console.log(
  n, typeof n
)

Круглі до 2 десяткових знаків, форматуйте як валюту із вказаним символом, використовуйте групування коми через тисячі:

console.log(
  68766.688689.toLocaleString('fullwide', {maximumFractionDigits:2, style:'currency', currency:'USD', useGrouping:true})   
)

Форматувати як валюту мови :

console.log(
  68766.688689.toLocaleString('fr-FR', {maximumFractionDigits:2, style:'currency', currency:'EUR'})   
)

Закруглюйте до мінімуму 3 десяткових знаків, примушуйте нулі відображати:

console.log(
  6.000000.toLocaleString('fullwide', {minimumFractionDigits:3})
)

Процентний стиль для співвідношень. Введення * 100 зі знаком%

console.log(
  6.688689.toLocaleString('fullwide', {maximumFractionDigits:2, style:'percent'})
)



1

У мене дуже хороше рішення, якщо toFixed () не працює.

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

Приклад

roundOff(10.456,2) //output 10.46


0

Незначні налаштування на цю відповідь :

function roundToStep(value, stepParam) {
   var step = stepParam || 1.0;
   var inv = 1.0 / step;
   return Math.round(value * inv) / inv;
}

roundToStep(2.55, 0.1) = 2.6
roundToStep(2.55, 0.01) = 2.55
roundToStep(2, 0.01) = 2

roundToStep (1.015, 0.002) дає 1.014. це правильний спосіб його використання
gaurav5430

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