66 Pertanyaan: Membulatkan ke paling banyak 2 tempat desimal (hanya jika perlu)

pertanyaan dibuat di Tue, Apr 30, 2019 12:00 AM

Saya ingin membulatkan paling banyak 2 tempat desimal, tetapi hanya jika perlu .

Input:

 
10
1.7777777
9.1

Output:

 
10
1.78
9.1

Bagaimana saya bisa melakukan ini di JavaScript?

    
2278
  1. Saya membuat biola dengan banyak teknik yang ditawarkan sebagai solusi di sini ... sehingga Anda dapat membandingkan: biola
    2013-11-18 09: 45: 13Z
  2. Sepertinya tidak ada yang menyadari Number.EPSILON . Gunakan Math.round( num * 100 + Number.EPSILON ) / 100.
    2017-01-18 09: 59: 30Z
  3. Untuk pembaca baru, Anda tidak dapat melakukan ini kecuali Anda memiliki hasil tipe string . Matematika titik apung pada representasi angka biner internal berarti ada angka selalu yang tidak dapat direpresentasikan sebagai desimal yang rapi.
    2018-02-20 01: 42: 05Z
  4. @ cronvel Bisakah Anda menjelaskan alasan penggunaan Number.EPSILON di sini?
    2018-10-19 03: 10: 40Z
30 Jawaban                              30                         

Gunakan Math.round(num * 100) / 100

    
2869
2013-03-14 20: 13: 38Z
  1. Meskipun ini akan bekerja untuk kebanyakan kasus, itu tidak akan bekerja untuk 1,005 yang akhirnya akan menjadi 1 bukannya 1,01
    2013-06-13 14: 33: 57Z
  2. @ James Wow itu benar-benar aneh- Saya sedang bekerja di konsol dev Chrome dan saya memperhatikan bahwa 1,005 * 100 = 100,4999999999999999. Math.round (100.49999999999999) mengevaluasi ke 100, sedangkan Math.round (100.5) mengevaluasi ke 101. IE9 melakukan hal yang sama. Ini karena keanehan floating point dalam javascript
    2013-07-26 17: 32: 41Z
  3. Solusi sederhana. Untuk 2 hari, gunakan Math.round((num + 0.00001) * 100) / 100. Coba Math.round((1.005 + 0.00001) * 100) / 100 dan Math.round((1.0049 + 0.00001) * 100) / 100
    2013-10-09 07: 01: 53Z
  4. @ mrkschan Mengapa itu berhasil, dan apakah itu sangat mudah untuk semua angka?
    2014-03-03 04: 45: 37Z
  5. Bagi Anda yang tidak mengerti teknik ini disebut scaling. Pada dasarnya apa yang dilakukan jawabannya di sini adalah membawa dua angka melintasi titik desimal mengubah angka menjadi bilangan bulat untuk menghindari semua masalah titik mengambang gila, bulatkan itu dan kemudian terjemahkan kembali menjadi seperti sebelumnya dengan membaginya dengan 100 dan Anda memiliki jawab 2dp.
    2014-11-14 18: 15: 19Z

Jika nilainya adalah jenis teks:

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

Jika nilainya adalah angka:

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

Ada downside yang nilai-nilai seperti 1,5 akan memberikan "1,50" sebagai output. Perbaikan yang disarankan oleh @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.

Sepertinya Math.round adalah solusi yang lebih baik. Tetapi tidak! Dalam beberapa kasus, TIDAK akan membulatkan dengan benar:

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

toFixed () juga akan TIDAK membulatkan dalam beberapa kasus (diuji di Chrome v.55.0.2883.87)!

Contoh:

 
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.

I guess, ini karena 1.555 sebenarnya seperti float 1.55499994 di belakang layar.

Solusi 1 adalah menggunakan skrip dengan algoritma pembulatan yang diperlukan, misalnya:

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

Solusi 2 adalah untuk menghindari perhitungan ujung depan dan menarik nilai bulat dari server backend.

    

2692
2017-05-26 19: 39: 33Z
  1. Pendekatan yang satu ini (theFixed) bagus, dan bekerja untuk saya, tetapi secara khusus tidak memenuhi permintaan asli "hanya bila perlu ". (Membulatkan 1,5 hingga 1,50, yang mematahkan spesifikasi.)
    2013-04-28 20: 09: 27Z
  2. Untuk persyaratan "bila perlu", lakukan ini: parseFloat(number.toFixed(decimalPlaces)); @ PerLundberg
    2013-12-30 02: 23: 19Z
  3. parseFloat("55.555").toFixed(2) mengembalikan "55.55" di konsol dev Chrome.
    2014-04-06 16: 02: 33Z
  4. Tidak ada keuntungan menggunakan toFixed alih-alih Math.round; toFixed mengarah ke masalah pembulatan yang sama (coba dengan 5.555 dan 1.005), tetapi lebih lambat 500x (tidak main-main) daripada Math.round ... Sepertinya jawaban @MarkG lebih akurat di sini.
    2014-05-20 16: 49: 34Z
  5. toFixed tidak "terkadang" mengembalikan sebuah string, ia selalu mengembalikan sebuah string.
    2014-06-25 20: 39: 42Z

Anda dapat menggunakan

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

Saya menemukan ini pada MDN . Cara mereka menghindari masalah dengan 1.005 yang disebutkan .

 
roundToTwo(1.005)
1.01
roundToTwo(10)
10
roundToTwo(1.7777777)
1.78
roundToTwo(9.1)
9.1
roundToTwo(1234.5678)
1234.57
    
398
2018-02-12 16: 11: 16Z
  1. @ Redsandro, +(val) adalah padanan paksaan untuk menggunakan Number(val). Menggabungkan "e-2" ke nomor menghasilkan string yang perlu dikonversi kembali ke angka.
    2014-02-28 19: 11: 48Z
  2. Berhati-hatilah bahwa untuk pelampung besar dan kecil yang akan menghasilkan NaN sejak, misalnya + "1e-21 + 2" tidak akan diuraikan dengan benar.
    2014-05-20 17: 13: 40Z
  3. Anda telah 'memecahkan' masalah '1.005, tetapi memperkenalkan yang baru: sekarang, di konsol Chrome, roundToTwo(1.0049999999999999) keluar sebagai 1,01 (pasti, sejak 1.0049999999999999 == 1.005 ). Sepertinya saya bahwa float yang Anda dapatkan jika Anda mengetik num = 1.005 'jelas' 'harus' dibulatkan ke 1,00, karena nilai pasti num kurang dari 1,005. Tentu saja, bagi saya nampaknya string '1,005' 'jelas' 'harus' dibulatkan ke 1,01. Fakta bahwa orang yang berbeda tampaknya memiliki intuisi yang berbeda tentang apa perilaku sebenarnya yang sebenarnya ada di sini adalah bagian dari mengapa itu rumit.
    2014-08-14 21: 56: 46Z
  4. Tidak ada angka (floating point) di antara 1.0049999999999999 dan 1.005, jadi menurut definisi, mereka adalah nomor yang sama. Ini disebut pemotongan dedekind.
    2015-02-18 00: 48: 55Z
  5. @ Azmisov benar. Sementara 1.00499 < 1.005 adalah true, 1.0049999999999999 < 1.005 dievaluasi menjadi false.
    2015-09-23 10: 55: 29Z

Jawaban MarkG adalah yang benar. Berikut ini adalah ekstensi umum untuk sejumlah tempat desimal.

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

Penggunaan:

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

Uji unit:

 
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');
  });
})
    
131
2013-11-01 07: 40: 59Z
  1. Pierre mengangkat masalah serius dengan jawaban MarkG.
    2014-06-18 16: 23: 40Z
  2. Catatan: Jika Anda tidak ingin mengubah Number.prototype - cukup tulis ini sebagai fungsi: function round(number, decimals) { return +(Math.round(number + "e+" + decimals) + "e-" + decimals); }
    2014-11-08 17: 28: 47Z
  3. Cara keren untuk mengembangkan ini. Anda dapat memeriksa apakah desimal negatif maka balikkan e + dan e-. Kemudian n = 115; n.round (-2); akan menghasilkan 100
    2016-03-23 ​​06: 28: 36Z
  4. Coba n: 1e + 19 - ia mengembalikan NaN
    2017-12-18 20: 59: 20Z
  5. Algoritma ini selalu dibulatkan ke atas (bukannya menjauh dari nol). Jadi, jika ada angka negatif, outputnya tidak seperti yang Anda harapkan: (-1.005).round(2) === -1
    2018-02-14 10: 51: 04Z

Seseorang dapat menggunakan .toFixed(NumberOfDecimalPlaces).

 
var str = 10.234.toFixed(2); // => '10.23'
var number = Number(str); // => 10.23
    
78
2017-05-18 16: 28: 29Z
  1. Mengapa ini bukan jawaban teratas ??? (EDIT: oh, karena itu dikonversi ke String :)
    2014-11-07 01: 05: 08Z
  2. Juga karena ia menambahkan angka nol, yang bukan apa yang ditanyakan oleh pertanyaan asli .
    2014-12-05 18: 38: 27Z
  3. Tetapi membuntuti nol dengan mudah dilucuti dengan sebuah regex, yaitu `Number (10.10000.toFixed (2) .replace (/0 + $/, ''))` = > 10.1
    2016-02-18 21: 31: 37Z
  4. @ daniel the jawaban teratas sama (seperti pada sekarang) tetapi tidak selalu membulat dengan benar, coba +(1.005).toFixed(2) yang mengembalikan 1, bukan 1.01.
    2016-11-01 19: 34: 15Z
  5. @ ChadMcElligott: Regex Anda tidak berfungsi dengan baik dengan bilangan bulat: Number(9).toFixed(2).replace(/0+$/, '') = > "9."
    2017-05-18 09: 41: 17Z

Pertanyaan ini rumit.

Misalkan kita memiliki fungsi, roundTo2DP(num), yang menggunakan float sebagai argumen dan mengembalikan nilai yang dibulatkan menjadi 2 tempat desimal. Apa yang harus dievaluasi dari masing-masing ekspresi ini?

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

Jawaban 'jelas' adalah bahwa contoh pertama harus dibulatkan menjadi 0,01 (karena lebih dekat dengan 0,01 daripada 0,02) sedangkan dua lainnya harus dibulatkan menjadi 0,02 (karena 0,015000000000000000001 lebih dekat ke 0,02 daripada 0,01, dan karena 0,015 adalah tepat di tengah-tengah antara mereka dan ada konvensi matematika bahwa angka-angka seperti itu dapat dibulatkan ke atas).

Hasil tangkapannya, yang mungkin sudah Anda duga, adalah bahwa roundTo2DP tidak mungkin diimplementasikan untuk memberikan jawaban yang jelas, karena ketiga angka yang diteruskan ke sana adalah angka yang sama . Angka-angka floating point biner IEEE 754 (jenis yang digunakan oleh JavaScript) tidak bisa persis mewakili sebagian besar angka-angka non-integer, dan ketiga literal numerik di atas dibulatkan ke titik mengambang terdekat yang valid, tanpa nomorer. Nomor ini, seperti yang terjadi, adalah tepatnya

0,01499999999999999944488848768742172978818416595458984375

yang lebih dekat ke 0,01 daripada 0,02.

Anda dapat melihat bahwa ketiga angka itu sama di konsol browser Anda, Node shell, atau penerjemah JavaScript lainnya. Bandingkan saja mereka:

 
> 0.014999999999999999 === 0.0150000000000000001
true

Jadi ketika saya menulis m = 0.0150000000000000001, nilai tepatnya dari m yang saya dapatkan lebih dekat dengan 0.01 daripada 0.02. Namun, jika saya mengonversi m ke sebuah String ...

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

... Saya mendapatkan 0,015, yang seharusnya membulatkan ke 0,02, dan yang jelas bukan angka 56-desimal-tempat saya sebelumnya mengatakan bahwa semua angka-angka ini persis sama dengan. Jadi sihir gelap apa ini?

Jawabannya dapat ditemukan dalam spesifikasi ECMAScript, di bagian 7.1.12.1: ToString diterapkan pada jenis Nomor . Di sini aturan untuk mengubah beberapa Number m menjadi sebuah String. Bagian kuncinya adalah poin 5, di mana integer s dihasilkan yang digitnya akan digunakan dalam representasi String dari m :

  

biarkan n , k , dan s menjadi bilangan bulat sehingga k ≥ 1, 10 k -1 s < 10 k , nilai angka untuk s × 10 n - k adalah m , dan k sekecil mungkin. Perhatikan bahwa k adalah jumlah digit dalam representasi desimal dari s , bahwa s tidak dapat dibagi dengan 10, dan bahwa digit paling signifikan dari s belum tentu ditentukan secara unik oleh kriteria ini.

Bagian kuncinya di sini adalah persyaratan bahwa " k sekecil mungkin". Apa yang dimaksud dengan jumlah tersebut adalah persyaratan yang, mengingat Nomor m, nilai String(m) harus memiliki jumlah digit paling sedikit sambil tetap memenuhi persyaratan yang Number(String(m)) === m. Karena kita sudah tahu 0.015 === 0.0150000000000000001 itu, sekarang sudah jelas mengapa String(0.0150000000000000001) === '0.015' pasti benar.

Tentu saja, tidak satu pun dari diskusi ini yang langsung menjawab apa yang harus dikembalikan roundTo2DP(m) . Jika nilai tepat m adalah 0,0149999999999999999944488848768742172978818416595458984375, tetapi representasi String-nya adalah '0,015', lalu apa jawaban benar - secara matematis, praktis, filosofis, atau apa pun - ketika kita membulatkannya ke dua tempat desimal?

Tidak ada jawaban yang benar untuk ini. Itu tergantung pada kasus penggunaan Anda. Anda mungkin ingin menghormati representasi String dan membulatkan ke atas ketika:

  • Nilai yang diwakili secara inheren diskrit, mis. sejumlah mata uang dalam mata uang 3 tempat desimal seperti dinar. Dalam kasus ini, nilai true dari Angka seperti 0,015 adalah 0,015, dan representasi 0,0149999999 ... yang didapat di binary floating point adalah kesalahan pembulatan. (Tentu saja, banyak yang akan berargumen, secara wajar, bahwa Anda harus menggunakan pustaka desimal untuk menangani nilai-nilai tersebut dan tidak pernah menyatakannya sebagai Angka titik mengambang biner.)
  • Nilai diketik oleh pengguna. Dalam kasus ini, sekali lagi, angka desimal persis yang dimasukkan lebih 'benar' daripada representasi titik mengambang biner terdekat.

Di sisi lain, Anda mungkin ingin menghormati nilai titik apung biner dan membulatkan ke bawah ketika nilai Anda berasal dari skala yang berkelanjutan secara inheren - misalnya, jika itu pembacaan dari sensor.

Kedua pendekatan ini membutuhkan kode yang berbeda. Untuk menghormati representasi String dari Angka, kita dapat (dengan sedikit kode yang cukup halus) menerapkan pembulatan kita sendiri yang bertindak langsung pada representasi String, digit demi digit, menggunakan algoritma yang sama yang akan Anda gunakan di sekolah ketika Anda diajarkan bagaimana membulatkan angka. Di bawah ini adalah contoh yang menghormati persyaratan OP untuk mewakili angka ke 2 tempat desimal "hanya jika perlu" dengan menelusur trailing nol setelah titik desimal; Anda mungkin, tentu saja, perlu menyesuaikannya dengan kebutuhan Anda yang sebenarnya.

 
/**
 * 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+$/, '')
}

Contoh penggunaan:

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

Fungsi di atas adalah mungkin yang ingin Anda gunakan untuk menghindari pengguna yang pernah menyaksikan angka yang mereka masukkan dibulatkan secara salah.

(Sebagai alternatif, Anda juga dapat mencoba perpustakaan round10 yang menyediakan fungsi yang berperilaku sama dengan implementasi yang sangat berbeda.)

Tetapi bagaimana jika Anda memiliki Nomor jenis kedua - nilai yang diambil dari skala berkelanjutan, di mana tidak ada alasan untuk berpikir bahwa perkiraan representasi desimal dengan lebih sedikit tempat desimal lebih akurat daripada yang memiliki lebih banyak ? Dalam hal ini, kami tidak ingin menghormati representasi String, karenase representasi itu (seperti yang dijelaskan dalam spesifikasi) sudah semacam bulat; kami tidak ingin membuat kesalahan dengan mengatakan "0,014999999 ... 375 putaran hingga 0,015, yang bulat hingga 0,02, jadi 0,014999999 ... 375 putaran hingga 0,02".

Di sini kita cukup menggunakan built-in toFixed metode. Perhatikan bahwa dengan memanggil Number() pada String yang dikembalikan oleh toFixed, kita mendapatkan Nomor yang representasi String-nya tidak memiliki angka nol (berkat cara JavaScript menghitung representasi String dari Angka, dibahas sebelumnya dalam jawaban ini).

 
/**
 * 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);
}
    
65
2017-06-01 20: 07: 48Z
  1. Ini tidak berfungsi dalam beberapa kasus tepi: coba ( jsfiddle ) dengan roundStringNumberWithoutTrailingZeroes(362.42499999999995, 2). Hasil yang diharapkan (seperti dalam PHP echo round(362.42499999999995, 2)): 362.43. Hasil aktual: 362.42
    2017-12-06 14: 11: 43Z
  2. @ Dr.GianluigiZaneZanettini Huh. Aneh. Saya tidak yakin mengapa PHP round memberi 362,43. Tampaknya secara intuitif salah, karena 362.4249999999999995 kurang dari 362.425 (dalam matematika dan kode - 362.42499999999995 < 362.425 benar dalam JS dan PHP). Jawaban PHP juga tidak meminimalkan jarak antara angka floating point asli dan bulat, sejak 362.43 - 362.42499999999995 > 362.42499999999995 - 362.42. Menurut php.net/manual/en/function.round.php , round PHP mengikuti standar C99; Saya harus menjelajah ke tanah C untuk memahami apa yang sedang terjadi.
    2017-12-06 14: 39: 04Z
  3. Setelah melihat implementasi pembulatan dalam sumber PHP , saya tidak tahu apa yang dilakukannya. Ini adalah implementasi yang sangat rumit penuh dengan makro dan cabang dan konversi string dan bercabang pada nilai-nilai presisi sihir hard-coded. Saya tidak yakin apa yang harus dikatakan di luar "Jawaban PHP salah, dan kita harus mengajukan laporan bug". Bagaimana Anda menemukan nomor 362.42499999999995, omong-omong?
    2017-12-06 22: 29: 26Z
  4. @ Dr.GianluigiZaneZanettini Saya telah membuat laporan bug: bugs.php.net/bug.php?id=75644
    2017-12-06 22: 48: 54Z
  5. Saya benar-benar berpikir bahwa PHP itu benar, karena 362.42499999999995 diakhiri dengan "5", jadi angkanya harus naik "naik", bukan "turun". Apakah saya masuk akal? Terima kasih atas upaya Anda! Saya menemukan nomor yang menerapkan diskon% pada harga.
    2017-12-07 16: 25: 11Z

Pertimbangkan .toFixed() dan .toPrecision():

http://www.javascriptkit.com/javatutors/formatnumber.shtml

    
64
2013-06-05 12: 25: 59Z
  1. toFixed menambahkan titik desimal ke setiap nilai, apa pun yang terjadi.
    2012-08-06 17: 22: 53Z
  2. Keduanya tidak berguna di sini
    2012-08-06 17: 23: 40Z
  3. Sayangnya, kedua fungsi ini akan menambah tempat desimal tambahan yang tampaknya tidak diinginkan oleh @stinkycheeseman.
    2012-08-06 17: 24: 18Z
  4. 2012-08-06 17: 30: 41Z
  5. mereka mengembalikan string dan bukan angka, sehingga mereka memformat dan tidak menghitung ..
    2016-07-14 09: 59: 33Z

Metode pembulatan yang tepat. Sumber: 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);
        };
    }
})();

Contoh:

 
// 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
    
62
2017-05-26 19: 46: 02Z
  1. Seseorang juga menaruh ini di GitHub dan npm: github .com /jhohlfeld /round10
    2016-06-03 21: 51: 08Z
  2. Tidak, Math.round10(3544.5249, -2) mengembalikan 3544.52 sebagai gantinya 3544.53
    2016-09-21 16: 29: 55Z
  3. @ Matija Wolfram alpha mengatakan 3544.52 juga. Anda ingin meminimalkan kesalahan antara angka saat ini dan perkiraan bulat. Perkiraan terdekat dari 3544.5249 ke 2 tempat desimal adalah 3544.52 (kesalahan = 0,0049). Jika 3544.53, kesalahannya adalah 0,0051. Anda melakukan pembulatan berturut-turut yaitu Math.round10 (Math.round10 (3544.5249, -3), -2) yang memberikan kesalahan pembulatan yang lebih besar dan karenanya tidak diinginkan.
    2016-09-21 17: 33: 19Z
  4. @ Matija, dari sudut pandang matematika, 3544.5249 bulat adalah 3544.52, bukan 3544.53, jadi kode ini benar. Jika Anda ingin membulatkannya ke 3544.53 dalam hal ini dan kasus-kasus seperti ini (bahkan sulit tidak benar), lakukan sesuatu seperti ini: number += 0.00011
    2016-11-16 15: 03: 41Z
  5. @ Matija: Saya pikir fungsinya berfungsi sebagaimana mestinya. Mungkin Anda ingin mengulangi pembulatan seperti: Math.round10( Math.round10(3544.5249, -3) , -2)
    2017-07-22 14: 31: 22Z

Tidak ada jawaban yang ditemukan di sini yang benar . @stinkycheeseman meminta mengumpulkan , Anda semua membulatkan angka.

Untuk menyimpulkan, gunakan ini:

 
Math.ceil(num * 100)/100;
    
58
2013-07-02-02 08: 18: 35Z
  1. Contoh input dan output menunjukkan bahwa meskipun pertanyaannya mengatakan 'kumpulkan ...' itu sebenarnya dimaksudkan sebagai 'bulat ke ...'.
    2013-07-05 04: 18: 10Z
  2. @ stinkycheeseman menunjukkan kesalahan dalam kasus tertentu, ia tidak ingin selalu terkurung seperti langit-langit, ia hanya ingin 0,005 untuk meringkas hingga 0,01
    2013-08-23 10: 17: 40Z
  3. Menemukan bug aneh saat menguji Math.ceil(1.1 * 100)/100; -itu mengembalikan 1.11, karena 1,1 * 100 adalah 110.00000000000001 menurut browser modern baru Firefox, Chrome, Safari dan Opera ... IE, dengan cara lama, masih dianggap 1.1*100=1100.
    2013-10-21 11: 57: 24Z
  4. @ skobaljic coba Math.ceil(num.toFixed(4) * 100) / 100
    2013-12-11 23: 07: 57Z
  5. @ treeface Math.ceil((1.1).toFixed(4) * 100) / 100 akanjuga mengembalikan 1.11 di Firefox, masalah /bug browser modern adalah dengan penggandaan dan orang-orang harus mengetahuinya (saya bekerja pada permainan lotre waktu itu misalnya).
    2014-01-09 09: 43: 48Z

Anda harus menggunakan:

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

Sepertinya tidak ada yang menyadari tentang Number.EPSILON .

Juga perlu dicatat bahwa ini bukan keanehan JavaScript seperti yang dinyatakan beberapa orang.

Begitulah cara angka floating point bekerja di komputer. Seperti 99% bahasa pemrograman, JavaScript tidak memiliki buatan rumah angka floating point; itu bergantung pada CPU /FPU untuk itu. Komputer menggunakan biner, dan dalam biner, tidak ada angka seperti 0.1, tetapi hanya perkiraan biner untuk itu. Mengapa? Untuk alasan yang sama dari 1/3 tidak dapat ditulis dalam desimal: nilainya 0,33333333 ... dengan infinity bertiga.

Ini dia Number.EPSILON . Angka itu adalah perbedaan antara angka 1 dan angka berikutnya yang ada dalam angka floating point presisi ganda. Itu dia: Tidak ada angka antara 1 dan 1 + Number.EPSILON.

Seperti yang ditanyakan dalam komentar, mari kita perjelas satu hal: menambahkan Number.EPSILON hanya relevan ketika nilai untuk dibulatkan adalah hasil dari operasi aritmatika, karena dapat menelan beberapa delta kesalahan titik apung.

Tidak berguna saat nilainya berasal dari sumber langsung (mis .: literal, input atau sensor pengguna).

    
50
2017-12-08 12: 29: 55Z
  1. Number.EPSILON tidak terdefinisi di Internet Explorer.
    2017-02-10 19: 09: 36Z
  2. @ palota Anda dapat mendefinisikan angka yang benar-benar seperti yang disebutkan cronvel EPSILON
    2017-05-24 15: 25: 10Z
  3. Ini adalah jawaban yang tepat! Masalahnya sendiri terkait dengan bagaimana angka float bekerja secara internal, bukan tentang javascript
    2017-05-24 15: 26: 04Z
  4. Sebenarnya, Anda harus menambahkan epsilon SEBELUM dikalikan 100. Math.round( (num + Number.EPSILON) * 100) / 100. Saya setuju juga ini adalah metode yang tepat untuk pembulatan yang benar (meskipun tidak persis apa yang ditanyakan dalam pertanyaan ini).
    2017-11-05 15: 30: 37Z
  5. - 1; mengapa saya harus menggunakan mantra sewenang-wenang ini? Apa yang akan dilakukannya ? Bagaimana hasilnya berbeda dengan jawaban lain di sini? Mengapa Number.EPSILON nilai yang berguna atau relevan? Terus terang, jawaban ini salah dan tidak masuk akal; dalam kebanyakan kasus, menambahkan Number.EPSILON tidak akan mengubah hasilnya, tetapi dalam satu-satunya kasus saya dapat membangun di mana itu berpengaruh, di mana num adalah 0,00499999999999999999, itu membuat hasilnya langsung salah, menyebabkan num dibulatkan menjadi 0,01 bila seharusnya dibulatkan dengan benar menjadi 0.
    2017-12-06 22: 01: 37Z

Ini cara mudah untuk melakukannya:

 
Math.round(value * 100) / 100

Anda mungkin ingin melanjutkan dan membuat fungsi terpisah untuk melakukannya untuk Anda:

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

Kemudian Anda cukup memberikan nilainya.

Anda bisa meningkatkannya menjadi angka desimal sewenang-wenang dengan menambahkan parameter kedua.

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

    return (Math.round(value * multiplier) / multiplier);
}
    
45
2013-06-05 12: 25: 44Z
  1. Solusi ini salah, lihat stackoverflow.com/questions/38322372/... jika Anda memasukkan 156893.145 dan memutarnya dengan fungsi di atas, Anda dapat 156893.14 bukannya 156893.15 !!!
    2016-07-14 09: 48: 14Z
  2. @ saimiris_devel, Anda telah berhasil menemukan contoh di mana representasi numerik angka dalam JavaScript gagal. Anda benar bahwa putarannya salah. Tapi - itu karena jumlah sampel Anda ketika dikalikan dengan 100 sudah rusak (15689314.499999998). Sungguh, jawaban berfitur lengkap akan membutuhkan perpustakaan yang telah dikembangkan secara khusus untuk memperhitungkan ketidakkonsistenan dalam penanganan JavaScript pada bilangan real. Jika tidak, Anda mungkin dapat membatalkan salah satu jawaban yang telah diberikan untuk pertanyaan ini.
    2018-11-10 23: 39: 29Z
 
+(10).toFixed(2); // = 10
+(10.12345).toFixed(2); // = 10.12

(10).toFixed(2); // = 10.00
(10.12345).toFixed(2); // = 10.12
    
36
2014-06-25 10: 27: 07Z
  1. Ini tidak akan selalu memberikan hasil yang sama dengan yang Anda dapatkan jika Anda mengambil representasi String dari Nomor Anda dan membulatkannya. Misalnya, +(0.015).toFixed(2) == 0.01.
    2016-07-30 17: 17: 08Z

Untuk saya Math.round () tidak memberikan jawaban yang benar. Saya menemukan toFixed (2) karya lebih baik. Berikut adalah contoh keduanya:

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

console.log(((43000 / 80000) * 100).toFixed(2)); // correct answer
    
36
2018-05-24 00: 32: 34Z
  1. Penting untuk dicatat bahwa toFixed tidak melakukan pembulatan, dan bahwa Math.round hanya membulatkan ke bilangan bulat terdekat. Untuk mempertahankan desimal, oleh karena itu kita perlu mengalikan angka asli dengan jumlah kekuatan sepuluh yang nolnya mewakili jumlah desimal yang Anda inginkan, dan kemudian membagi hasilnya dengan angka yang sama. Dalam kasus Anda: Math.round (43000/80000 * 100 * 100) /100. Akhirnya toFixed (2) dapat diterapkan untuk memastikan bahwa selalu ada dua desimal dalam hasil (dengan membuntuti nol di mana diperlukan) - sempurna untuk meluruskan serangkaian angka yang disajikan secara vertikal :)
    2018-05-01 14: 26: 35Z
  2. Juga penting untuk dicatat bahwa .toFIxed () menghasilkan string, bukan angka.
    2018-06-26 16: 19: 23Z
  3. Ini masih belum menyelesaikan pembulatan untuk 1.005. (1.005).toFixed(2) masih menghasilkan hingga 1.00.
    2018-10-26 15: 46: 11Z



Cukup gunakan kode asli .toFixed()

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

Jika Anda harus ketat dan menambahkan angka hanya jika diperlukan dapat menggunakan replace

 
number = 1; // "1"
number.toFixed(5).replace(/\.?0*$/g,'');
    
33
2017-12-17 09: 56: 22Z
  1. Metode toFixed mengembalikan sebuah string. Jika Anda menginginkan hasil angka, Anda harus mengirim hasil toFixed ke parseFloat.
    2017-11-07 20: 04: 24Z
  2. @ Zambonilli Atau cukup kalikan dengan 1 jikaitu perlu. tetapi karena angka tetap, sebagian besar case adalah untuk tampilan dan bukan untuk string perhitungan adalah format yang tepat
    2017-11-08 13: 05: 43Z
  3. - 1; bukan saja toFixed disarankan oleh beberapa jawaban bertahun-tahun sebelum jawaban Anda, tetapi juga gagal memenuhi persyaratan "hanya jika perlu" dalam pertanyaan; (1).toFixed(2) memberi "1.00" di mana si penanya menginginkan "1".
    2017-12-07 00: 02: 49Z
  4. Ok mengerti. Saya menambahkan beberapa solusi juga untuk kasus ini
    2017-12-14 17: 05: 28Z
  5. Jika Anda menggunakan lodash, bahkan lebih mudah: _.round (angka, decimalPlace) Menghapus komentar terakhir saya, karena ada masalah. Lodash _.round TIDAK berfungsi, meskipun. 1,005 dengan tempat desimal 2 yang dikonversi menjadi 1,01.
    2018-07-31 17: 40: 59Z

Gunakan fungsi ini Number(x).toFixed(2);

    
33
2018-12-10 13: 00: 10Z
  1. Bungkus semuanya di Number lagi, jika Anda tidak ingin itu dikembalikan sebagai string: Number(Number(x).toFixed(2));
    2015-09-12 05: 17: 22Z
  2. Panggilan Number tidak diperlukan, x.toFixed(2) berfungsi.
    2018-12-14 16: 09: 36Z
  3. @ bgusach Panggilan nomor diperlukan, karena pernyataan x.toFixed (2) mengembalikan string dan bukan angka. Untuk mengonversi lagi ke angka, kita perlu membungkusnya dengan Angka
    2019-03-15 06: 26: 59Z
  4. Saat menggunakan metode ini (1).toFixed(2) mengembalikan 1.00, tetapi penanya membutuhkan 1 dalam kasus ini.
    2019-06-07 20: 40: 40Z

Coba solusi ringan ini:

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

 round(1.222,  2) ;
 // 1.22
 round(1.222, 10) ;
 // 1.222
    
31
2014-10-20 10: 21: 12Z
  1. Adakah yang tahu apakah ada perbedaan antara ini dan return Number(x.toFixed(digits))?
    2015-09-12 05: 16: 08Z
  2. @ JoeRocc ... seharusnya tidak membuat perbedaan sejauh yang dapat saya lihat karena .toFixed() hanya mengizinkan angka saja.
    2015-09-12 10: 16: 25Z
  3. Jawaban ini memiliki masalah yang sama seperti yang disebutkan beberapa kali di halaman ini. Coba round(1.005, 2) dan lihat hasil 1 alih-alih 1.01.
    2016-08-05 06: 54: 53Z
  4. tampaknya lebih merupakan masalah pembulatan algo? - ada lebih dari satu yang dibayangkan: en.wikipedia.org/wiki/Rounding .. round(0.995, 2) => 0.99; round(1.006, 2) => 1.01; round(1.005, 2) => 1
    2018-02-07 05: 35: 17Z

Ada beberapa cara untuk melakukan itu. Untuk orang-orang seperti saya, varian 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))
}

 

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

Jika proyek Anda menggunakan jQuery atau lodash, Anda juga dapat menemukan metode round yang tepat di perpustakaan.

Perbarui 1

Saya menghapus varian n.toFixed(2), karena itu tidak benar. Terima kasih @ avalanche1

    
28
2017-06-22 13: 48: 11Z
  1. Pilihan kedua akan mengembalikan sebuah string dengan tepat dua titik desimal. Pertanyaannya hanya meminta titik desimal jika perlu. Opsi pertama lebih baik dalam hal ini.
    2016-07-05 13: 36: 31Z
  2. @ MarcosLima Number.toFixed() akan mengembalikan sebuah string tetapi dengan simbol plus di depannya, JS interpreter akan mengubah string tersebut menjadi angka. Ini adalah gula sintaks.
    2016-07-05 14: 04: 45Z
  3. Di Firefox, alert((+1234).toFixed(2)) menunjukkan "1234.00".
    2016-07-05 14: 11: 54Z
  4. Di Firefox, alert(+1234.toFixed(2)) melempar SyntaxError: identifier starts immediately after numeric literal. Saya tetap dengan opsi 1.
    2016-07-05 15: 19: 06Z
  5. Semua varian memberikan solusi yang salah untuk 0.015
    2017-01-25 12: 37: 40Z

MarkG dan Lavamantis menawarkan solusi yang jauh lebih baik daripada yang telah diterima. Sayang sekali mereka tidak mendapatkan lebih banyak upvotes!

Ini adalah fungsi yang saya gunakan untuk menyelesaikan masalah desimal floating point juga berdasarkan MDN . Itu bahkan lebih umum (tapi kurang ringkas) daripada solusi 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));
}

Gunakan dengan:

 
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

Dibandingkan dengan solusi Lavamantis, kita dapat melakukan ...

 
round(1234.5678, -2); // Returns 1200
round("123.45");      // Returns 123
    
22
2014-01-24 15: 44: 06Z
  1. Solusi Anda tidak mencakup beberapa kasus yang bertentangan dengan solusi MDN. Meskipun mungkin lebih pendek, itu tidak akurat ...
    2015-07-05 21: 42: 55Z
  2. round (-1835.665,2) = > -1835.66
    2016-07-29 01: 38: 35Z

Jika Anda menggunakan perpustakaan lodash, Anda dapat menggunakan metode bundar dari Lodash seperti berikut.

 
_.round(number, precision)

Misalnya:

 
_.round(1.7777777, 2) = 1.78
    
20
2017-07-28 06: 59: 19Z
  1. @ Peter Himpunan fungsi yang disediakan Lodash sangat bagus dibandingkan dengan Javascript standar. Namun, saya mendengar bahwa Lodash memiliki beberapa masalah kinerja dibandingkan dengan JS standar. codeburst.io/…
    2018-10-04 08: 26: 31Z
  2. Saya menerima pendapat Anda bahwa ada kekurangan kinerja dengan menggunakan lodash. Saya pikir masalah-masalah itu biasa terjadi pada banyak abstraksi. Tapi lihat saja berapa banyak jawaban yang ada di utas ini dan bagaimana solusi intuitif gagal untuk kasus tepi. Kami telah melihat pola ini dengan jQuery dan masalah root terpecahkan ketika browser mengadopsi standar umum yang memecahkan sebagian besar kasus penggunaan kami. Kemacetan kinerja kemudian dipindahkan ke mesin peramban. Saya pikir hal yang sama harus terjadi pada lodash. :)
    2018-10-04 10: 17: 31Z

Ini dapat membantu Anda:

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

untuk lebih lanjutinformasi, Anda dapat melihat tautan ini

Math.round (num) vs num. toFixed (0) dan inkonsistensi peramban

    
18
2017-05-23 11: 55: 00Z
 
var roundUpto = function(number, upto){
    return Number(number.toFixed(upto));
}
roundUpto(0.1464676, 2);

toFixed(2) di sini 2 adalah jumlah digit hingga kami ingin membulatkan angka ini.

    
16
2015-06-02 07: 15: 38Z
  1. this .toFixed () lebih mudah diimplementasikan. cukup telusuri sekali.
    2015-05-15 07: 19: 20Z

Mungkin berhasil untuk Anda,

 
Math.round(num * 100)/100;

untuk mengetahui perbedaan antara toFixed dan round. Anda dapat melihat di Math.round (num) vs num.toFixed (0) dan inkonsistensi peramban .

    
14
2017-05-26 19: 36: 50Z

Karena ES6 ada cara yang 'tepat' (tanpa mengesampingkan statika dan membuat penyelesaian masalah) untuk melakukan ini dengan menggunakan 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));

maka Anda hanya dapat parseFloat dan nol akan 'hilang'.

 
console.log(parseFloat((1.4999).toPrecision(3)));
console.log(parseFloat((1.005).toPrecision(3)));
console.log(parseFloat((1.0051).toPrecision(3)));
    
14
2019-06-08 04: 59: 59Z
  1. (1.005).toPrecision(3) masih mengembalikan 1.00, bukannya 1.01 sebenarnya.
    2018-02-23 22: 21: 07Z
  2. toPrecision mengembalikan string yang mengubah tipe keluaran yang diinginkan.
    2018-11-16 22: 59: 49Z
  3. @ Giacomo Ini bukan cacat dari metode .toPrecision, ini adalah kekhususan angka floating-point (yang angka dalam JS) - coba 1.005 - 0.005, ia akan mengembalikan 0.9999999999999999 .
    2018-11-26 01: 44: 24Z
  4. (1).toPrecision(3) mengembalikan '1,00', tetapi penanya ingin memiliki 1 dalam kasus ini.
    2019-06-07 20: 39: 31Z
  5. Ini juga mungkin tidak melakukan apa yang diinginkan kebanyakan orang dengan angka yang lebih besar tanpa desimal - katakanlah 144. Itu akan dibulatkan menjadi 140.
    2019-06-28 17: 19: 14Z

Cara termudah:

+num.toFixed(2)

Ini mengubahnya menjadi string, dan kemudian kembali menjadi integer /float.

    
13
2015-02-25 20: 09: 30Z
  1. Terima kasih atas jawaban yang paling sederhana ini. Namun, apa yang '+' dalam + num? Itu tidak bekerja untuk saya di mana val desimal datang dalam string. Saya melakukannya: (num * 1) .toFixed (2).
    2015-03-22 08:21: 20Z
  2. Ini tidak mencakup 1,005, @Lihat stackoverflow.com/a/29924251/961018
    2015-04-28 15: 59: 04Z
  3. @ momo ubah saja argumennya menjadi toFixed() menjadi 3. Jadi itu akan menjadi +num.toFixed(3). Itu bekerja dengan cara yang seharusnya, 1,005 dibulatkan menjadi 1,00, yang sama dengan 1
    2015-05-04 16: 13: 56Z
  4. @ Edmund Seharusnya mengembalikan 1,01, bukan 1,00
    2015-05-05 19: 20: 36Z

Gunakan sesuatu seperti ini "parseFloat (parseFloat (nilai) .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
2018-03-26 08: 26: 56Z
  1. ini adalah satu-satunya jawaban yang benar di halaman ini.
    2018-07-09 14: 08: 42Z
  2. tidak jika ketidaktepatan intrinsik dengan representasi float. Anda hanya akan menghapusnya dan kemudian memperkenalkan kembali kesalahan yang sama dengan mengonversi kembali ke float lagi!
    2018-10-28 20: 00: 32Z

Berikut adalah metode prototipe:

 
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
2017-05-26 19: 43: 00Z

Secara umum, pembulatan dilakukan dengan penskalaan: round(num / p) * p

Menggunakan notasi eksponensial menangani pembulatan + ve angka, dengan benar. Namun, metode ini gagal membulatkan tepi-kasus dengan benar.

 
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

Di sini, juga merupakan salah satu fungsi yang saya tulis untuk melakukan pembulatan aritmatika dengan benar. Anda dapat mengujinya sendiri.

 
/**
 * 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
2018-02-13 10: 23: 22Z

Untuk tidak berurusan dengan banyak 0s, gunakan varian ini:

 
Math.round(num * 1e2) / 1e2
    
10
2013-10-11 15: 21: 39Z

Jika Anda sudah menggunakan pustaka d3, mereka memiliki pustaka pemformatan angka yang kuat: https: //github. com /mbostock /d3 /wiki /Memformat

Pembulatan ada di sini: ​​https://github.com/mbostock/d3/wiki/Formatting#d3_round

Dalam kasus Anda, jawabannya adalah:

 
> d3.round(1.777777, 2)
1.78
> d3.round(1.7, 2)
1.7
> d3.round(1, 2)
1
    
9
2014-06-18 13: 35: 04Z
  1. Melihat sumber , ini tidak lebih dari versi umum jawaban @ustasb, menggunakan num * Math.pow(n) dan bukan num * 100 (tapi ini jelas merupakan one-liner ;-)
    2014-06-18 14: 23: 13Z
  2. Tapididokumentasikan, dan, berada di perpustakaan, saya tidak memiliki kebutuhan yang sama untuk memeriksa kompatibilitas BS browser.
    2014-06-19 18: 11: 20Z
  3. menggunakan Math.pow (n) memungkinkan untuk d3.round (12, -1) == 10
    2014-08-05 09: 25: 53Z

Salah satu cara untuk mencapai pembulatan hanya jika diperlukan adalah dengan menggunakan Number.prototype.toLocaleString () :

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

Ini akan memberikan hasil persis seperti yang Anda harapkan, tetapi sebagai string. Anda masih dapat mengonversi angka itu kembali ke angka jika itu bukan tipe data yang Anda harapkan.

    
9
2017-02-22 21: 32: 54Z
  1. Ini adalah solusi terbersih yang ada sejauh ini dan menghindari semua masalah floating point yang rumit, tetapi per MDN dukungan masih belum lengkap - Safari belum mendukung meneruskan argumen ke toLocaleString.
    2016-07-30 23: 12: 09Z
sumber ditempatkan sini