Bulat untuk paling banyak 2 tempat desimal (hanya jika diperlukan)
I'd seperti untuk putaran paling banyak 2 tempat desimal, tetapi hanya jika diperlukan.
Input:
10
1.7777777
9.1
Output:
10
1.78
9.1
Bagaimana saya bisa melakukan ini di JavaScript?
2465
71
Gunakan
Matematika.bulat(num * 100) / 100
Jika nilai adalah jenis teks:
Jika nilai adalah nomor:
Ada sisi negatifnya bahwa nilai-nilai seperti 1.5 akan memberikan "1.50" sebagai output. Perbaikan yang disarankan oleh @minitech:
Sepertinya
Matematika.bulat
adalah solusi yang lebih baik. Tapi itu tidak! Dalam beberapa kasus itu akan TIDAK **** putaran dengan benar:toFixed() juga akan TIDAK bulat dengan benar dalam beberapa kasus (diuji di Chrome v. 55.0.2883.87)!
Contoh:
Saya kira, ini karena 1.555 adalah benar-benar sesuatu seperti mengapung 1.55499994 di belakang layar.
Solusi 1 adalah dengan menggunakan script dengan yang dibutuhkan algoritma pembulatan, misalnya:
https://plnkr.co/edit/uau8BlS1cqbvWPCHJeOy?p=preview
Solusi 2 adalah untuk menghindari front end perhitungan dan menarik nilai bulat dari backend server.
Anda dapat menggunakan
Saya menemukan ini di atas pada MDN. Cara mereka menghindari masalah dengan 1.005 yang sebutkan.
MarkG's jawaban yang benar. Berikut ini's generik ekstensi untuk setiap jumlah tempat desimal.
Penggunaan:
Unit test:
Anda harus menggunakan:
Tidak ada yang tampaknya menyadari
Nomor.EPSILON
.Juga's dicatat bahwa ini bukan JavaScript keanehan seperti beberapa orang menyatakan.
Itu hanya cara angka floating point bekerja di komputer. Seperti 99% bahasa pemrograman, JavaScript doesn't memiliki home made angka floating point; hal ini bergantung pada CPU/FPU untuk itu. Menggunakan komputer biner dan biner, ada isn't setiap nomor seperti
0.1
, tapi hanya biner pendekatan untuk itu. Mengapa? Untuk alasan yang sama dari 1/3 tidak dapat dituliskan dalam desimal: nilainya 0.33333333... dengan infinity bertiga.Di sini datang
Nomor.EPSILON
. Jumlah itu merupakan selisih antara 1 dan berikutnya nomor ada di double precision floating point nomor. Yang's ini: Ada tidak ada jumlah antara1
dan 1 +Nomor.EPSILON
.EDIT:
Seperti yang ditanyakan di komentar, let's menjelaskan satu hal: menambahkan
Nomor.EPSILON
hanya relevan ketika nilai untuk putaran adalah hasil dari operasi aritmatika, karena dapat menelan beberapa floating point kesalahan delta.It's tidak berguna ketika nilai berasal dari sumber langsung (misalnya: literal, input pengguna atau sensor).
EDIT (2019):
Seperti @maganap dan beberapa orang telah menunjukkan, itu's terbaik untuk menambahkan
Nomor.EPSILON
sebelum mengalikan:Satu dapat menggunakan
.toFixed(NumberOfDecimalPlaces)
.Pertimbangkan
.toFixed()
dan.toPrecision()
:http://www.javascriptkit.com/javatutors/formatnumber.shtml
Pertanyaan ini lebih rumit. Misalkan kita memiliki sebuah fungsi,
roundTo2DP(num)
, yang mengambil pelampung sebagai argumen dan mengembalikan nilai dibulatkan sampai 2 tempat desimal. Apa yang harus masing-masing ekspresi yang mengevaluasi ke?roundTo2DP(0.014999999999999999)
roundTo2DP(0.0150000000000000001)
roundTo2DP(0.015)
The 'jelas' jawabannya adalah bahwa contoh pertama harus bulat untuk 0.01 (karena itu's lebih dekat dari 0.01 ke 0.02) sementara dua lainnya harus bulat untuk 0.02 (karena 0.0150000000000000001 lebih dekat ke 0.02 dari 0,01, dan karena 0.015 adalah persis di tengah antara mereka dan ada matematika konvensi bahwa angka tersebut mendapatkan dibulatkan). Menangkap, yang anda mungkin telah menebak, adalah bahwaroundTo2DP
tidak bisa dilaksanakan untuk memberikan mereka jawaban yang jelas, karena semua tiga angka yang diberikan adalah nomor yang sama. IEEE 754 biner angka floating point (jenis yang digunakan oleh JavaScript) dapat't persis mewakili sebagian besar non-integer angka, dan semua tiga literal numerik di atas bisa dibulatkan ke terdekat valid floating point nomor. Jumlah ini, seperti yang terjadi, persis 0.01499999999999999944488848768742172978818416595458984375 yang lebih dekat dari 0.01 ke 0.02. Anda dapat melihat bahwa semua tiga nomor yang sama di konsol browser anda, Node shell, atau JavaScript penerjemah. Bandingkan saja mereka: Jadi ketika saya menulis `m = 0.0150000000000000001`, yang *nilai yang tepat dari `m`* yang aku end up dengan lebih dekat ke `0.01` daripada `0.02`. Namun, jika saya convert `m` untuk String... ... Saya mendapatkan 0.015, yang harus bulat untuk 0.02, dan yang jelas *tidak* 56 desimal-tempat nomor saya sebelumnya mengatakan bahwa semua angka-angka ini persis sama dengan. Jadi apa sihir gelap ini? Jawabannya dapat ditemukan dalam ECMAScript spesifikasi, di bagian [*7.1.12.1: ToString diterapkan untuk Jumlah jenis*](http://www.ecma-international.org/ecma-262/7.0/#sec-tostring-applied-to-the-number-type). Berikut ini aturan untuk mengkonversi beberapa Nomor *m* untuk String yang ditetapkan. Bagian penting adalah point 5, di mana integer *s* dihasilkan dan angka yang akan digunakan dalam representasi String dari *m*: > biarkan *n*, *k*, dan *s* menjadi bilangan bulat sedemikian sehingga *k* ≥ 1, 10k-1 ≤ *s* < 10k, Jumlah nilai *s* × 10n-k adalah *m*, dan *k* adalah sekecil mungkin. Perhatikan bahwa k adalah jumlah digit dalam representasi desimal *s*, yang *s* tidak habis dibagi dengan 10, dan yang paling signifikan digit *s* tidak selalu unik ditentukan oleh kriteria-kriteria tersebut. Bagian penting di sini adalah persyaratan yang "*k* adalah sekecil mungkin". Apa persyaratan bahwa jumlah ini adalah persyaratan yang, diberi Nomor `m`, nilai `String(m)` harus memiliki *yang paling mungkin jumlah digit* sementara masih memenuhi persyaratan bahwa `Jumlah(String(m)) === m`. Karena kita sudah tahu bahwa `0.015 === 0.0150000000000000001`, it's sekarang jelas mengapa `String(0.0150000000000000001) === '0.015'` harus benar. Tentu saja, tidak ada pembahasan ini telah dijawab langsung apa `roundTo2DP(m)` *harus* kembali. Jika `m`'s nilai yang tepat adalah 0.01499999999999999944488848768742172978818416595458984375, tetapi representasi String adalah '0.015', lalu apa *benar* menjawab secara matematis, praktis, filosofis, atau apa pun - ketika kita putaran ke dua tempat desimal? Tidak ada satu jawaban yang benar untuk ini. Hal ini tergantung pada kasus penggunaan anda. Anda mungkin ingin menghormati representasi String dan bulat ke atas ketika:Contoh penggunaan:
Fungsi di atas adalah *mungkin* apa yang ingin anda gunakan untuk menghindari pengguna yang pernah menyaksikan angka-angka yang mereka telah masuk menjadi bulat salah. (Sebagai alternatif, anda bisa juga mencoba [round10](https://github.com/jhohlfeld/round10) perpustakaan yang menyediakan sama-berperilaku fungsi dengan liar implementasi yang berbeda.) Tetapi bagaimana jika anda memiliki kedua jenis Nomor - nilai yang diambil dari terus menerus skala, di mana ada's tidak ada alasan untuk berpikir bahwa perkiraan representasi desimal dengan lebih sedikit desimal yang lebih akurat ** dari orang-orang dengan lebih banyak? Dalam hal ini, kita *don't* ingin menghormati representasi String, karena representasi itu (seperti yang dijelaskan di spec) sudah sort-of-bulat; kami don't ingin membuat kesalahan dengan mengatakan "0.014999999...375 putaran sampai 0.015, yang putaran hingga 0.02, jadi 0.014999999...375 putaran sampai 0.02". Di sini kita hanya dapat menggunakan built-in [`toFixed`](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) metode. Perhatikan bahwa dengan memanggil `Nomor()` pada String yang dikembalikan oleh `toFixed`, kita mendapatkan Jumlah dan representasi String tidak memiliki ekor angka nol (terima kasih untuk jalan JavaScript menghitung representasi String dari Nomor, yang dibahas sebelumnya dalam jawaban ini).Tepat metode pembulatan. Sumber: Mozilla
Contoh:
Tidak ada jawaban yang ditemukan di sini adalah benar. @stinkycheeseman diminta untuk round up, anda semua bulat nomor.
Untuk round up, gunakan ini:
Berikut ini adalah cara sederhana untuk melakukannya:
Anda mungkin ingin pergi ke depan dan membuat fungsi yang terpisah untuk melakukannya untuk anda meskipun:
Kemudian anda hanya akan lulus dalam nilai.
Anda bisa meningkatkan ke putaran untuk setiap sewenang-wenang jumlah desimal dengan menambahkan parameter kedua.
Bagi saya Matematika.round() tidak memberikan jawaban yang benar. Saya menemukan toFixed(2) karya-karya yang lebih baik. Di bawah ini adalah contoh kedua:
Gunakan fungsi ini
Nomor(x).toFixed(2);
Coba ini ringan solusi:
Dua ribu tujuh belas Hanya menggunakan kode asli
.toFixed()
Jika anda perlu untuk menjadi ketat dan tambahkan digit hanya jika diperlukan dapat menggunakan
menggantikan
Ada beberapa cara untuk melakukan itu. Untuk orang-orang seperti saya, Lodash's varian
Penggunaan:
Jika proyek anda menggunakan jQuery atau lodash, anda juga bisa menemukan yang tepat
bulat
metode di perpustakaan.Update 1
Saya dihapus varian
n.toFixed(2)
, karena itu tidak benar. Terima kasih @avalanche1Jika anda menggunakan lodash perpustakaan, anda dapat menggunakan round metode lodash seperti berikut.
Misalnya:
MarkG dan Lavamantis ditawarkan sebuah solusi yang jauh lebih baik daripada yang telah diterima. It's rasa malu mereka don't mendapatkan lebih banyak upvotes!
Berikut adalah fungsi yang saya gunakan untuk memecahkan floating point desimal masalah juga didasarkan pada MDN. Hal ini bahkan lebih generik (tapi kurang ringkas) dari Lavamantis's solusi:
Menggunakannya dengan:
Dibandingkan dengan Lavamantis's solusi, yang bisa kita lakukan...
Sejak ES6 ada 'tepat' cara (tanpa mengesampingkan statika dan menciptakan workarounds) untuk melakukan hal ini dengan menggunakan toPrecision
maka anda hanya dapat
parseFloat
dan nol akan 'pergi'.konsol.log(parseFloat((1.4999).toPrecision(3))); konsol.log(parseFloat((1.005).toPrecision(3))); konsol.log(parseFloat((1.0051).toPrecision(3)));