Helpex - Trao đổi & giúp đỡ Đăng nhập
2141

Tôi muốn làm tròn tối đa 2 chữ số thập phân, nhưng chỉ khi cần thiết .

Đầu vào:

10
1.7777777
9.1

Đầu ra:

10
1.78
9.1

Làm thế nào tôi có thể làm điều này trong JavaScript?

2141 hữu ích 4 bình luận 1.9m xem chia sẻ
64 trả lời 64
2737

Sử dụng Math.round(num * 100) / 100

2737 hữu ích 5 bình luận chia sẻ
2613

Nếu giá trị là một loại văn bản:

parseFloat("123.456").toFixed(2);

Nếu giá trị là một số:

var numb = 123.23454;
numb = numb.toFixed(2);

Có một nhược điểm là các giá trị như 1.5 sẽ cho "1,50" làm đầu ra. Một bản sửa lỗi được đề xuất bởi @minitech:

var numb = 1.5;
numb = +numb.toFixed(2);
// Note the plus sign that drops any "extra" zeroes at the end.
// It changes the result (which is a string) into a number again (think "0 + foo"),
// which means that it uses only as many digits as necessary.

Có vẻ như Math.roundlà một giải pháp tốt hơn. Nhưng nó không phải như vậy! Trong một số trường hợp, nó sẽ KHÔNG làm tròn chính xác:

Math.round(1.005 * 1000)/1000 // Returns 1 instead of expected 1.01!

toFixed () cũng sẽ KHÔNG làm tròn chính xác trong một số trường hợp (được thử nghiệm trong Chrome v.55.0.2883.87)!

Ví dụ:

parseFloat("1.555").toFixed(2); // Returns 1.55 instead of 1.56.
parseFloat("1.5550").toFixed(2); // Returns 1.55 instead of 1.56.
// However, it will return correct result if you round 1.5551.
parseFloat("1.5551").toFixed(2); // Returns 1.56 as expected.

1.3555.toFixed(3) // Returns 1.355 instead of expected 1.356.
// However, it will return correct result if you round 1.35551.
1.35551.toFixed(2); // Returns 1.36 as expected.

Tôi đoán, điều này là bởi vì 1.555 thực sự là một cái gì đó giống như float 1.55499994 đằng sau hậu trường.

Giải pháp 1 là sử dụng tập lệnh với thuật toán làm tròn yêu cầu, ví dụ:

function roundNumber(num, scale) {
  if(!("" + num).includes("e")) {
    return +(Math.round(num + "e+" + scale)  + "e-" + scale);
  } else {
    var arr = ("" + num).split("e");
    var sig = ""
    if(+arr[1] + scale > 0) {
      sig = "+";
    }
    return +(Math.round(+arr[0] + "e" + sig + (+arr[1] + scale)) + "e-" + scale);
  }
}

https://plnkr.co/edit/uau8BlS1cqbvWPCHJeOy?p=preview

Giải pháp 2 là tránh tính toán giao diện người dùng và kéo các giá trị làm tròn từ máy chủ phụ trợ.

2613 hữu ích 5 bình luận chia sẻ
379

Bạn có thể dùng

function roundToTwo(num) {    
    return +(Math.round(num + "e+2")  + "e-2");
}

Tôi tìm thấy điều này trên MDN . Cách của họ tránh được vấn đề với 1.005 đã được đề cập .

roundToTwo(1.005)
1.01
roundToTwo(10)
10
roundToTwo(1.7777777)
1.78
roundToTwo(9.1)
9.1
roundToTwo(1234.5678)
1234.57
379 hữu ích 5 bình luận chia sẻ
125

Câu trả lời của MarkG là câu trả lời đúng. Đây là một phần mở rộng chung cho bất kỳ số vị trí thập phân.

Number.prototype.round = function(places) {
  return +(Math.round(this + "e+" + places)  + "e-" + places);
}

Sử dụng:

var n = 1.7777;    
n.round(2); // 1.78

Bài kiểm tra đơn vị:

it.only('should round floats to 2 places', function() {

  var cases = [
    { n: 10,      e: 10,    p:2 },
    { n: 1.7777,  e: 1.78,  p:2 },
    { n: 1.005,   e: 1.01,  p:2 },
    { n: 1.005,   e: 1,     p:0 },
    { n: 1.77777, e: 1.8,   p:1 }
  ]

  cases.forEach(function(testCase) {
    var r = testCase.n.round(testCase.p);
    assert.equal(r, testCase.e, 'didn\'t get right number');
  });
})
125 hữu ích 5 bình luận chia sẻ
77

Người ta có thể sử dụng .toFixed(NumberOfDecimalPlaces).

var str = 10.234.toFixed(2); // => '10.23'
var number = Number(str); // => 10.23
77 hữu ích 5 bình luận chia sẻ
61

Câu hỏi này rất phức tạp.

Giả sử chúng ta có một hàm, roundTo2DP(num)lấy một số float làm đối số và trả về giá trị được làm tròn đến 2 vị trí thập phân. Mỗi biểu thức này nên đánh giá cái gì?

  • roundTo2DP(0.014999999999999999)
  • roundTo2DP(0.0150000000000000001)
  • roundTo2DP(0.015)

Câu trả lời 'rõ ràng' là ví dụ đầu tiên nên làm tròn đến 0,01 (vì nó gần 0,01 hơn 0,02) trong khi hai ví dụ còn lại làm tròn đến 0,02 (vì 0,0150000000000000001 gần với 0,02 hơn 0,01 và vì 0,015 nằm chính xác giữa chúng và có một quy ước toán học rằng những con số như vậy được làm tròn lên).

Điều mà bạn có thể đoán được là roundTo2DP không thể thực hiện được để đưa ra những câu trả lời rõ ràng đó, bởi vì cả ba số được truyền cho nó đều là cùng một số . Các số dấu phẩy động nhị phân của IEEE 754 (loại được sử dụng bởi JavaScript) không thể biểu thị chính xác hầu hết các số không nguyên và vì vậy cả ba chữ số ở trên được làm tròn thành một số dấu phẩy động hợp lệ gần đó. Con số này, như nó xảy ra, là chính xác

0,01199999999999999944488848768742172978818416595458984375

gần với 0,01 hơn 0,02.

Bạn có thể thấy rằng cả ba số đều giống nhau trên bảng điều khiển trình duyệt, trình bao Node hoặc trình thông dịch JavaScript khác. Chỉ cần so sánh chúng:

> 0.014999999999999999 === 0.0150000000000000001
true

Vì vậy, khi tôi viết m = 0.0150000000000000001, giá trị chính xác củam cái mà tôi kết thúc gần 0.01với nó hơn 0.02. Tuy nhiên, nếu tôi chuyển đổi mthành Chuỗi ...

> var m = 0.0150000000000000001;
> console.log(String(m));
0.015
> var m = 0.014999999999999999;
> console.log(String(m));
0.015

... Tôi nhận được 0,015, làm tròn đến 0,02 và đáng chú ý không phải là số thập phân 56 mà tôi đã nói trước đó nói rằng tất cả các số này đều chính xác bằng. Vậy ma thuật đen tối này là gì?

Câu trả lời có thể được tìm thấy trong đặc tả ECMAScript, trong phần 7.1.12.1: ToString được áp dụng cho loại Số . Ở đây các quy tắc để chuyển đổi một số Số m thành Chuỗi được đặt ra. Phần quan trọng là điểm 5, trong đó một số nguyên s được tạo ra có chữ số sẽ được sử dụng trong chuỗi đại diện của m :

Đặt n , ks là các số nguyên sao cho k ≥ 1, 10 k -1s <10 k , giá trị Số cho s × 10 n - kmk càng nhỏ càng tốt. Lưu ý rằng k là số chữ số trong biểu diễn thập phân của s , s đó không chia hết cho 10 và chữ số có nghĩa nhỏ nhất của s không nhất thiết phải được xác định duy nhất bởi các tiêu chí này.

Phần quan trọng ở đây là yêu cầu " k càng nhỏ càng tốt". Yêu cầu đó là bao nhiêu là một yêu cầu, với một Số m, giá trị của String(m)phải có số chữ số ít nhất có thể trong khi vẫn đáp ứng yêu cầu đó Number(String(m)) === m. Vì chúng ta đã biết điều đó 0.015 === 0.0150000000000000001, giờ thì rõ ràng tại sao String(0.0150000000000000001) === '0.015'phải đúng.

Tất nhiên, không có cuộc thảo luận nào đã trả lời trực tiếp những gì roundTo2DP(m) nên trả lại. Nếu mgiá trị chính xác là 0,01199999999999999944488848768742172978818416595458984375, nhưng biểu diễn Chuỗi của nó là '0,015', thì câu trả lời đúng - về mặt toán học, thực tế, triết học hay bất cứ điều gì - khi chúng ta làm tròn nó thành hai số thập phân?

Không có câu trả lời đúng duy nhất cho điều này. Nó phụ thuộc vào trường hợp sử dụng của bạn. Bạn có thể muốn tôn trọng biểu diễn Chuỗi và làm tròn lên khi:

  • Giá trị được đại diện là rời rạc, ví dụ như một lượng tiền tệ trong một loại tiền có 3 chữ số thập phân như dinar. Trong trường hợp này, giá trị thực của một Số như 0,015 0,015 và đại diện 0,0119999999 ... mà nó nhận được ở dấu phẩy động nhị phân là lỗi làm tròn. (Tất nhiên, nhiều người sẽ tranh luận, một cách hợp lý, rằng bạn nên sử dụng thư viện thập phân để xử lý các giá trị đó và không bao giờ biểu thị chúng dưới dạng Số dấu phẩy động nhị phân ở vị trí đầu tiên.)
  • Giá trị được gõ bởi một người dùng. Trong trường hợp này, một lần nữa, số thập phân chính xác được nhập là "đúng" hơn so với biểu diễn dấu phẩy động nhị phân gần nhất.

Mặt khác, bạn có thể muốn tôn trọng giá trị dấu phẩy động nhị phân và làm tròn xuống khi giá trị của bạn từ thang đo liên tục vốn có - ví dụ, nếu đó là cách đọc từ cảm biến.

Hai cách tiếp cận này yêu cầu mã khác nhau. Để tôn trọng biểu diễn Chuỗi của Số, chúng tôi có thể (với khá nhiều mã tinh tế hợp lý) thực hiện làm tròn số riêng của chúng tôi hoạt động trực tiếp trên biểu diễn Chuỗi, chữ số theo chữ số, sử dụng cùng thuật toán bạn đã sử dụng ở trường khi bạn được dạy cách làm tròn số. Dưới đây là một ví dụ tôn trọng yêu cầu của OP về việc biểu thị số đến 2 vị trí thập phân "chỉ khi cần thiết" bằng cách tước các số 0 ở sau dấu thập phân; tất nhiên, bạn có thể cần phải điều chỉnh nó theo nhu cầu chính xác của mình.

/**
 * Converts num to a decimal string (if it isn't one already) and then rounds it
 * to at most dp decimal places.
 *
 * For explanation of why you'd want to perform rounding operations on a String
 * rather than a Number, see http://stackoverflow.com/a/38676273/1709587
 *
 * @param {(number|string)} num
 * @param {number} dp
 * @return {string}
 */
function roundStringNumberWithoutTrailingZeroes (num, dp) {
    if (arguments.length != 2) throw new Error("2 arguments required");

    num = String(num);
    if (num.indexOf('e+') != -1) {
        // Can't round numbers this large because their string representation
        // contains an exponent, like 9.99e+37
        throw new Error("num too large");
    }
    if (num.indexOf('.') == -1) {
        // Nothing to do
        return num;
    }

    var parts = num.split('.'),
        beforePoint = parts[0],
        afterPoint = parts[1],
        shouldRoundUp = afterPoint[dp] >= 5,
        finalNumber;

    afterPoint = afterPoint.slice(0, dp);
    if (!shouldRoundUp) {
        finalNumber = beforePoint + '.' + afterPoint;
    } else if (/^9+$/.test(afterPoint)) {
        // If we need to round up a number like 1.9999, increment the integer
        // before the decimal point and discard the fractional part.
        finalNumber = Number(beforePoint)+1;
    } else {
        // Starting from the last digit, increment digits until we find one
        // that is not 9, then stop
        var i = dp-1;
        while (true) {
            if (afterPoint[i] == '9') {
                afterPoint = afterPoint.substr(0, i) +
                             '0' +
                             afterPoint.substr(i+1);
                i--;
            } else {
                afterPoint = afterPoint.substr(0, i) +
                             (Number(afterPoint[i]) + 1) +
                             afterPoint.substr(i+1);
                break;
            }
        }

        finalNumber = beforePoint + '.' + afterPoint;
    }

    // Remove trailing zeroes from fractional part before returning
    return finalNumber.replace(/0+$/, '')
}

Ví dụ sử dụng:

> roundStringNumberWithoutTrailingZeroes(1.6, 2)
'1.6'
> roundStringNumberWithoutTrailingZeroes(10000, 2)
'10000'
> roundStringNumberWithoutTrailingZeroes(0.015, 2)
'0.02'
> roundStringNumberWithoutTrailingZeroes('0.015000', 2)
'0.02'
> roundStringNumberWithoutTrailingZeroes(1, 1)
'1'
> roundStringNumberWithoutTrailingZeroes('0.015', 2)
'0.02'
> roundStringNumberWithoutTrailingZeroes(0.01499999999999999944488848768742172978818416595458984375, 2)
'0.02'
> roundStringNumberWithoutTrailingZeroes('0.01499999999999999944488848768742172978818416595458984375', 2)
'0.01'

Chức năng trên có lẽ là những gì bạn muốn sử dụng để tránh người dùng chứng kiến ​​những con số mà họ đã nhập bị làm tròn sai.

(Để thay thế, bạn cũng có thể thử thư viện round10 cung cấp chức năng tương tự với cách triển khai cực kỳ khác biệt.)

Nhưng điều gì sẽ xảy ra nếu bạn có loại Số thứ hai - một giá trị được lấy từ thang đo liên tục, trong đó không có lý do gì để nghĩ rằng các biểu diễn thập phân gần đúng với số thập phân ít chính xác hơn các số có nhiều số thập phân hơn? Trong trường hợp đó, chúng tôi không muốn tôn trọng biểu diễn Chuỗi, vì biểu diễn đó (như được giải thích trong thông số kỹ thuật) đã được sắp xếp theo thứ tự; chúng tôi không muốn phạm sai lầm khi nói "0,011999999 ... 375 vòng lên tới 0,015, làm tròn đến 0,02, vì vậy 0,011999999 ... 375 vòng lên 0,02".

Ở đây chúng ta chỉ cần sử dụng toFixedphương thức tích hợp sẵn. Lưu ý rằng bằng cách gọi Number()Chuỗi được trả về bởi toFixed, chúng ta sẽ nhận được một Số có biểu diễn Chuỗi không có các số 0 ở cuối (nhờ cách JavaScript tính toán biểu diễn Chuỗi của một Số, đã thảo luận trước đó trong câu trả lời này).

/**
 * Takes a float and rounds it to at most dp decimal places. For example
 *
 *     roundFloatNumberWithoutTrailingZeroes(1.2345, 3)
 *
 * returns 1.234
 *
 * Note that since this treats the value passed to it as a floating point
 * number, it will have counterintuitive results in some cases. For instance,
 * 
 *     roundFloatNumberWithoutTrailingZeroes(0.015, 2)
 *
 * gives 0.01 where 0.02 might be expected. For an explanation of why, see
 * http://stackoverflow.com/a/38676273/1709587. You may want to consider using the
 * roundStringNumberWithoutTrailingZeroes function there instead.
 *
 * @param {number} num
 * @param {number} dp
 * @return {number}
 */
function roundFloatNumberWithoutTrailingZeroes (num, dp) {
    var numToFixedDp = Number(num).toFixed(dp);
    return Number(numToFixedDp);
}
61 hữu ích 5 bình luận chia sẻ
60

Một phương pháp làm tròn chính xác. Nguồn: Mozilla

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

// 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
// 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
60 hữu ích 5 bình luận chia sẻ
59
59 hữu ích 5 bình luận chia sẻ
56

Không có câu trả lời nào được tìm thấy ở đây là chính xác . @stinkycheeseman yêu cầu làm tròn , tất cả các bạn làm tròn số.

Để làm tròn, sử dụng:

Math.ceil(num * 100)/100;
56 hữu ích 5 bình luận chia sẻ
48

Bạn nên sử dụng:

Math.round( num * 100 + Number.EPSILON ) / 100

Không ai có thể nhận thức được Number.EPSILON.

Ngoài ra, điều đáng chú ý là đây không phải là một sự kỳ lạ của JavaScript như một số người đã nêu.

Đó chỉ đơn giản là cách các số dấu phẩy động hoạt động trong máy tính. Giống như 99% ngôn ngữ lập trình, JavaScript không có số dấu phẩy động tại nhà ; nó dựa vào CPU / FPU cho điều đó. Một máy tính sử dụng nhị phân và trong nhị phân, không có bất kỳ số nào giống như 0.1, nhưng chỉ là xấp xỉ nhị phân cho điều đó. Tại sao? Vì lý do tương tự, hơn 1/3 không thể được viết bằng số thập phân: giá trị của nó là 0,3333333 ... với vô số ba mươi.

Dưới đây đi Number.EPSILON. Con số đó là sự khác biệt giữa 1 và số tiếp theo tồn tại trong các số dấu phẩy động chính xác kép. Đó là: Không có số giữa 1và 1 + Number.EPSILON.

CHỈNH SỬA:

Như được hỏi trong các ý kiến, chúng ta hãy làm rõ một điều: việc thêm Number.EPSILONchỉ có liên quan khi giá trị làm tròn là kết quả của phép toán số học, vì nó có thể nuốt một số lỗi delta dấu phẩy động.

Nó không hữu ích khi giá trị đến từ một nguồn trực tiếp (ví dụ: nghĩa đen, đầu vào của người dùng hoặc cảm biến).

48 hữu ích 5 bình luận chia sẻ
44

Đây là một cách đơn giản để làm điều đó:

Math.round(value * 100) / 100

Bạn có thể muốn tiếp tục và tạo một chức năng riêng để làm điều đó cho bạn:

function roundToTwo(value) {
    return(Math.round(value * 100) / 100);
}

Sau đó, bạn chỉ cần vượt qua trong giá trị.

Bạn có thể cải thiện nó để làm tròn đến bất kỳ số thập phân tùy ý nào bằng cách thêm một tham số thứ hai.

function myRound(value, places) {
    var multiplier = Math.pow(10, places);

    return (Math.round(value * multiplier) / multiplier);
}
44 hữu ích 3 bình luận chia sẻ
36
+(10).toFixed(2); // = 10
+(10.12345).toFixed(2); // = 10.12

(10).toFixed(2); // = 10.00
(10.12345).toFixed(2); // = 10.12
36 hữu ích 1 bình luận chia sẻ
35

Đối với tôi Math.round () đã không đưa ra câu trả lời đúng. Tôi thấy toFixed (2) hoạt động tốt hơn. Dưới đây là ví dụ của cả hai:

console.log(Math.round(43000 / 80000) * 100); // wrong answer

console.log(((43000 / 80000) * 100).toFixed(2)); // correct answer

35 hữu ích 3 bình luận chia sẻ
33

2017
Chỉ cần sử dụng mã gốc.toFixed()

number = 1.2345;
number.toFixed(2) // "1.23"

Nếu bạn cần nghiêm ngặt và thêm chữ số nếu cần, nó có thể sử dụng replace

number = 1; // "1"
number.toFixed(5).replace(/\.?0*$/g,'');
33 hữu ích 5 bình luận chia sẻ
31

Hãy thử giải pháp trọng lượng nhẹ này :

function round(x, digits){
  return parseFloat(x.toFixed(digits))
}

 round(1.222,  2) ;
 // 1.22
 round(1.222, 10) ;
 // 1.222
31 hữu ích 5 bình luận chia sẻ
29

Sử dụng chức năng này Number(x).toFixed(2);

29 hữu ích 3 bình luận chia sẻ
28

Có một vài cách để làm điều đó. Đối với những người như tôi, biến thể của Lodash

function round(number, precision) {
    var pair = (number + 'e').split('e')
    var value = Math.round(pair[0] + 'e' + (+pair[1] + precision))
    pair = (value + 'e').split('e')
    return +(pair[0] + 'e' + (+pair[1] - precision))
}

Sử dụng:

round(0.015, 2) // 0.02
round(1.005, 2) // 1.01

Nếu dự án của bạn sử dụng jQuery hoặc lodash, bạn cũng có thể tìm thấy roundphương thức thích hợp trong các thư viện.

Cập nhật 1

Tôi loại bỏ các biến thể n.toFixed(2), bởi vì nó không chính xác. Cảm ơn bạn @ avalanche1

28 hữu ích 5 bình luận chia sẻ
22

MarkG và Lavamantis đưa ra một giải pháp tốt hơn nhiều so với giải pháp đã được chấp nhận. Thật xấu hổ khi họ không nhận được nhiều sự ủng hộ hơn!

Đây là chức năng tôi sử dụng để giải quyết các vấn đề về số thập phân dấu phẩy động cũng dựa trên MDN . Nó thậm chí còn chung chung (nhưng ít súc tích hơn) so với giải pháp của Lavamantis:

function round(value, exp) {
  if (typeof exp === 'undefined' || +exp === 0)
    return Math.round(value);

  value = +value;
  exp  = +exp;

  if (isNaN(value) || !(typeof exp === 'number' && exp % 1 === 0))
    return NaN;

  // Shift
  value = value.toString().split('e');
  value = Math.round(+(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));
}

Sử dụng nó với:

round(10.8034, 2);      // Returns 10.8
round(1.275, 2);        // Returns 1.28
round(1.27499, 2);      // Returns 1.27
round(1.2345678e+2, 2); // Returns 123.46

So với giải pháp của Lavamantis, chúng ta có thể ...

round(1234.5678, -2); // Returns 1200
round("123.45");      // Returns 123
22 hữu ích 2 bình luận chia sẻ
20

Nếu bạn đang sử dụng thư viện lodash, bạn có thể sử dụng phương pháp vòng của lodash như sau.

_.round(number, precision)

Ví dụ:

_.round(1.7777777, 2) = 1.78
20 hữu ích 3 bình luận chia sẻ
16

Điều này có thể giúp bạn:

var result = (Math.round(input*100)/100);

để biết thêm thông tin, bạn có thể xem liên kết này

Math.round (num) so với num.toFixed (0) và sự không nhất quán của trình duyệt

16 hữu ích 0 bình luận chia sẻ
16
var roundUpto = function(number, upto){
    return Number(number.toFixed(upto));
}
roundUpto(0.1464676, 2);

toFixed(2) ở đây 2 là số chữ số mà chúng tôi muốn làm tròn số này.

16 hữu ích 2 bình luận chia sẻ
13

Sử dụng cái gì đó như thế này "parseFloat (parseFloat (value) .toFixed (2))"

parseFloat(parseFloat("1.7777777").toFixed(2))-->1.78 
parseFloat(parseFloat("10").toFixed(2))-->10 
parseFloat(parseFloat("9.1").toFixed(2))-->9.1
13 hữu ích 2 bình luận chia sẻ
12

Cách dễ nhất:

+num.toFixed(2)

Nó chuyển đổi nó thành một chuỗi, và sau đó trở lại thành một số nguyên / float.

12 hữu ích 4 bình luận chia sẻ
12

Nó có thể làm việc cho bạn,

Math.round(num * 100)/100;

để biết sự khác biệt giữa toFixed và round. Bạn có thể xem Math.round (num) vs num.toFixed (0) và sự không nhất quán của trình duyệt .

12 hữu ích 0 bình luận chia sẻ
12

Đây là một phương pháp nguyên mẫu:

Number.prototype.round = function(places){
    places = Math.pow(10, places); 
    return Math.round(this * places)/places;
}

var yournum = 10.55555;
yournum = yournum.round(2);
12 hữu ích 0 bình luận chia sẻ
11

Nói chung, làm tròn được thực hiện bằng cách chia tỷ lệ: round(num / p) * p

Sử dụng ký hiệu số mũ xử lý làm tròn số + ve, chính xác. Tuy nhiên, phương pháp này không thành công cho các trường hợp cạnh tròn chính xác.

function round(num, precision = 2) {
	var scaled = Math.round(num + "e" + precision);
	return Number(scaled + "e" + -precision);
}

// testing some edge cases
console.log( round(1.005, 2) );  // 1.01 correct
console.log( round(2.175, 2) );  // 2.18 correct
console.log( round(5.015, 2) );  // 5.02 correct

console.log( round(-1.005, 2) );  // -1    wrong
console.log( round(-2.175, 2) );  // -2.17 wrong
console.log( round(-5.015, 2) );  // -5.01 wrong

Đây cũng là một hàm tôi đã viết để làm tròn số học một cách chính xác. Bạn có thể tự kiểm tra nó.

/**
 * MidpointRounding away from zero ('arithmetic' rounding)
 * Uses a half-epsilon for correction. (This offsets IEEE-754
 * half-to-even rounding that was applied at the edge cases).
 */

function RoundCorrect(num, precision = 2) {
	// half epsilon to correct edge cases.
	var c = 0.5 * Number.EPSILON * num;
//	var p = Math.pow(10, precision); //slow
	var p = 1; while (precision--> 0) p *= 10;
	if (num < 0)
		p *= -1;
	return Math.round((num + c) * p) / p;
}

// testing some edge cases
console.log(RoundCorrect(1.005, 2));  // 1.01 correct
console.log(RoundCorrect(2.175, 2));  // 2.18 correct
console.log(RoundCorrect(5.015, 2));  // 5.02 correct

console.log(RoundCorrect(-1.005, 2));  // -1.01 correct
console.log(RoundCorrect(-2.175, 2));  // -2.18 correct
console.log(RoundCorrect(-5.015, 2));  // -5.02 correct

11 hữu ích 1 bình luận chia sẻ
10

Để không đối phó với nhiều số 0, hãy sử dụng biến thể này:

Math.round(num * 1e2) / 1e2
10 hữu ích 0 bình luận chia sẻ
9

Nếu bạn tình cờ đã sử dụng thư viện d3, họ có thư viện định dạng số mạnh mẽ: https://github.com/mbostock/d3/wiki/Formatted

Làm tròn cụ thể là ở đây: https://github.com/mbostock/d3/wiki/Formatted#d3_round

Trong trường hợp của bạn, câu trả lời là:

> d3.round(1.777777, 2)
1.78
> d3.round(1.7, 2)
1.7
> d3.round(1, 2)
1
9 hữu ích 3 bình luận chia sẻ
9

Vì ES6 có cách 'phù hợp' (không ghi đè thống kê và tạo cách giải quyết) để thực hiện việc này bằng cách sử dụng toPrecision

var x = 1.49999999999;
console.log(x.toPrecision(4));
console.log(x.toPrecision(3));
console.log(x.toPrecision(2));

var y = Math.PI;
console.log(y.toPrecision(6));
console.log(y.toPrecision(5));
console.log(y.toPrecision(4));

var z = 222.987654
console.log(z.toPrecision(6));
console.log(z.toPrecision(5));
console.log(z.toPrecision(4));

9 hữu ích 3 bình luận chia sẻ
8

Một cách để đạt được làm tròn như vậy chỉ khi cần thiết là sử dụng Number.prototype.toLocaleString () :

myNumber.toLocaleString('en', {maximumFractionDigits:2, useGrouping:false})

Điều này sẽ cung cấp chính xác đầu ra mà bạn mong đợi, nhưng dưới dạng chuỗi. Bạn vẫn có thể chuyển đổi các số đó thành số nếu đó không phải là loại dữ liệu bạn mong đợi.

8 hữu ích 1 bình luận chia sẻ
loading
Không tìm thấy câu trả lời bạn tìm kiếm? Duyệt qua các câu hỏi được gắn thẻ javascript decimal rounding decimal-point , hoặc hỏi câu hỏi của bạn.

Có thể bạn quan tâm

loading