Làm thế nào để làm tròn số float trong javascript?


298

Tôi cần phải tròn ví dụ 6.688689để 6.7, nhưng nó luôn luôn chỉ cho tôi 7.

Phương pháp của tôi:

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

Nhưng kết quả luôn giống nhau 7... Tôi đang làm gì sai?


28
(6.688689​).toFixed(1);
Shadow Wizard là Ear For You

Kiểm tra cái này
raina77ow

có thể trùng lặp số vòng trong JavaScript thành N số thập phân - vui lòng sử dụng tìm kiếm trước khi bạn đặt câu hỏi mới.
Felix Kling


1
@ShadowWizard là chính xác. Tuy nhiên, .toFixedtrả về một chuỗi. Hãy chắc chắn để bọc kết quả trong Number(). Xem câu trả lời được chấp nhận, và những người khác.
Jordan Arseno

Câu trả lời:


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

22
Chuyển một số thành một chuỗi và sau đó trở lại? Điều đó không thể nhanh được.
csl

không tốt nếu số của bạn có số thập phân ít hơn mức cần thiết. Nó thêm một số
njzk2

2
như hiển thị điểm chuẩn của JS, nó chậm hơn phương thức
@fivingigit

13
Number((456.1235).toFixed(3)) -> 456.123, Number((1.235).toFixed(2)) -> 1.24... Ngu ngốc JavaScript ...
Noone

6
Điều này có thể KHÔNG làm những gì bạn mong đợi! Kết quả thậm chí có thể phụ thuộc vào trình duyệt, xem câu hỏi này: stackoverflow.com/q/566564/2224996
maja

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

13
Điều này không phải lúc nào cũng hoạt động. Lấy Math.round(1.005*100)/100ví dụ từ MDN
tybro0103

7
@ tybro0103 Điểm nổi ác: 1.005 * 100 = 100.49999999999999(ít nhất là trong công cụ JS tôi đã thử). Đó là lý do tại sao nó không hoạt động và tại sao bạn không bao giờ nên dựa vào phao là hoàn toàn chính xác.
sudo

1
Sai lầm. Math.round (1.015 * 100) / 100 trả về 1.01 thay vì 1.02
Marco Marsala

81

Sử dụng toFixed()chức năng.

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

5
Điều này có thể KHÔNG làm những gì bạn mong đợi! Kết quả thậm chí có thể phụ thuộc vào trình duyệt, xem câu hỏi này: stackoverflow.com/q/566564/2224996
maja

9
(6.688689) .toFixed (); bằng "7" chứ không phải 7. Tương tự cho các ví dụ khác.
Vado

35

Cập nhật (2019-10). Nhờ mã Reece Daniels dưới đây hiện có sẵn dưới dạng tập hợp các hàm được đóng gói trong vòng npm-gói dự kiến (hãy xem).


Bạn có thể sử dụng chức năng trợ giúp từ ví dụ MDN . Hơn bạn sẽ linh hoạt hơn:

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

Cập nhật (2019-01-15). Có vẻ như các tài liệu MDN không còn có chức năng trợ giúp này nữa. Đây là một bản sao lưu với các ví dụ:

// 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);
    };
  }
})();

Ví dụ sử dụng:

// 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 không phải là một chức năng"
Peter Krauss

1
Tôi thấy điều này cực kỳ hữu ích vì vậy đã đưa nó vào một gói npm nhanh chóng cho những người muốn sử dụng nó mà không cần thêm mã. Được ghi có @aspanchenko với câu trả lời ban đầu: npmjs.com/package/azed-round
Reece Daniels

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

Một Numberđối tượng trong JavaScript có một phương thức thực hiện chính xác những gì bạn cần. Phương pháp đó là Number.toPrecision([precision]).

Giống như với .toFixed(1)nó, chuyển đổi kết quả thành một chuỗi và nó cần được chuyển đổi lại thành một số. Thực hiện bằng cách sử dụng +tiền tố ở đây.

điểm chuẩn đơn giản trên máy tính xách tay của tôi:

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

Theo tôi đây là câu trả lời tốt nhất (tốt nhất theo cách thực hành tốt nhất, cách tiếp cận đơn giản nhất).
cezar

1
1e-10.toPrecision(3): "1,00e-10" - vòng này đến các chữ số có nghĩa .
Vsevolod Golovanov

9

Nếu bạn không chỉ muốn sử dụng toFixed()mà còn ceil()floor()trên phao thì bạn có thể sử dụng chức năng sau:

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

Sản xuất:

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

CẬP NHẬT:

Cách khác có thể là đây:

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

Sản xuất:

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

Làm thế nào để chúng ta quyết định khi nào nên sử dụng trần, sàn hoặc tròn để làm tròn? Ví dụ: roundUsing (Math.round, 1.015, 2) roundUsing (Math.ceil, 1.015, 2) đưa ra 2 giá trị khác nhau Làm thế nào để chúng ta biết nên sử dụng cái nào
gaurav5430

7

Chức năng vòng mở rộng của tôi:

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);
  }
} 

Kết quả ví dụ:

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
điều này tương tự như câu trả lời của @ fiveigit. vòng (1.015, 2) vẫn cho 1.01 thay vì 1.02
gaurav5430

@ gaurav5430, cảm ơn báo cáo của bạn, tôi đã sửa nó.
Nick Tsai

6

Xem bên dưới

var original = 28.59;

var result=Math.round(original*10)/10 sẽ trả lại bạn trở về 28.6

Hy vọng đây là những gì bạn muốn ..


7
"Nếu tôi có một xu cho mỗi lần tôi thấy ai đó sử dụng FLOAT để lưu trữ tiền tệ, tôi sẽ có $ 999,997634" - Bill Karwin.
emix

2
Sai lầm. Math.round (1.015 * 100) / 100
Marco Marsala

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

Tôi nghĩ rằng chức năng này có thể giúp đỡ.

 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

tương tự như một số câu trả lời khác, điều này không thành công cho vòng (1.015, 2), sẽ cho 1.02
gaurav5430

1

Tôi nghĩ chức năng dưới đây có thể giúp

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));
}

sử dụng: roundOff(600.23458,2);sẽ trở lại600.23


Bạn có thể giải thích những gì câu trả lời này thêm rằng chưa được bao phủ bởi các câu trả lời trước?
stealththeninja

tương tự như một số câu trả lời khác, điều này không thành công cho vòng (1.015, 2), sẽ cho 1.02
gaurav5430

1

nếu bạn đang ở trong bối cảnh của node.js, bạn có thể thử mathjs

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

1

.toLocaleString () thay thế cho định dạng số, với rất nhiều tùy chọn liên quan đến địa phương, nhóm, định dạng tiền tệ, ký hiệu. Vài ví dụ:

Làm tròn đến 1 số thập phân, trả về số float:

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

Làm tròn đến 2 số thập phân, định dạng dưới dạng tiền tệ với ký hiệu được chỉ định, sử dụng nhóm dấu phẩy cho hàng nghìn:

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

Định dạng là tiền địa phương :

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

Làm tròn đến tối thiểu 3 số thập phân, buộc các số không hiển thị:

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

Tỷ lệ phần trăm cho tỷ lệ. Nhập * 100 với dấu%

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


1
+((6.688689 * (1 + Number.EPSILON)).toFixed(1)); // 6.7
+((456.1235 * (1 + Number.EPSILON)).toFixed(3)); // 456.124

1

Tôi có giải pháp rất tốt với nếu toFixed () không hoạt động.

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

Thí dụ

roundOff(10.456,2) //output 10.46

0

Nếu bạn đang sử dụng Browserify hôm nay, bạn sẽ phải thử: làm tròn Để một NPM lib rất hữu ích


0

Điều chỉnh nhỏ cho câu trả lời này :

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) cho 1.014. đó có phải là cách chính xác để sử dụng nó
gaurav5430

@ gaurav5430 thửroundToStep(1.015, 0.001)
Crashalot
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.