Dalam JavaScript, ketika mengkonversi dari float ke string, bagaimana saya bisa mendapatkan hanya 2 digit setelah titik desimal? Misalnya, 0,34 bukannya 0,3445434.
Dalam JavaScript, ketika mengkonversi dari float ke string, bagaimana saya bisa mendapatkan hanya 2 digit setelah titik desimal? Misalnya, 0,34 bukannya 0,3445434.
Jawaban:
var result = Math.round(original*100)/100;
Spesifikasinya , jika kodenya tidak jelas.
sunting: ... atau gunakan saja toFixed
, seperti yang diusulkan oleh Tim Büthe . Lupa itu, terima kasih (dan upvote) untuk pengingat :)
toFixed()
akan meniru apa yang dilakukan sesuatu printf()
dalam C. Namun, toFixed()
dan Math.round()
akan menangani pembulatan berbeda. Dalam hal ini, toFixed()
akan memiliki efek yang sama Math.floor()
akan (jika Anda mengalikan aslinya dengan 10 ^ n sebelumnya, dan menelepon toFixed()
dengan n digit). "Kebenaran" jawabannya sangat tergantung pada apa yang diinginkan OP di sini, dan keduanya "benar" dengan caranya sendiri.
Ada fungsi untuk membulatkan angka. Sebagai contoh:
var x = 5.0364342423;
print(x.toFixed(2));
akan mencetak 5.04.
EDIT: Fiddle
var x = 5.036432346; var y = x.toFixed(2) + 100;
y
akan sama"5.03100"
(0.335).toFixed(2) == 0.34 == (0.345).toFixed(2)
...
Hati-hati saat menggunakan toFixed()
:
Pertama, pembulatan angka dilakukan dengan menggunakan representasi biner dari angka tersebut, yang dapat menyebabkan perilaku yang tidak terduga. Sebagai contoh
(0.595).toFixed(2) === '0.59'
bukannya '0.6'
.
Kedua, ada bug IE dengan toFixed()
. Di IE (setidaknya hingga versi 7, tidak memeriksa IE8), hal berikut ini berlaku:
(0.9).toFixed(0) === '0'
Mungkin ide yang baik untuk mengikuti saran kkyy atau menggunakan toFixed()
fungsi kustom , misalnya
function toFixed(value, precision) {
var power = Math.pow(10, precision || 0);
return String(Math.round(value * power) / power);
}
.toFixed()
metode asli dalam nilai kembali, yang akan menambah jumlah presisi yang diperlukan, misalnya: return (Math.round(value * power) / power).toFixed(precision);
dan juga mengembalikan nilai sebagai string. Jika tidak, ketelitian 20 diabaikan untuk desimal yang lebih kecil
toFixed
: perhatikan bahwa meningkatkan presisi dapat menghasilkan hasil yang tidak terduga:, (1.2).toFixed(16) === "1.2000000000000000"
sementara (1.2).toFixed(17) === "1.19999999999999996"
(di Firefox / Chrome; di IE8 yang terakhir tidak berlaku karena presisi yang lebih rendah yang ditawarkan IE8 secara internal).
(0.598).toFixed(2)
tidak menghasilkan 0.6
. Ini menghasilkan 0.60
:)
(0.335).toFixed(2) == 0.34 == (0.345).toFixed(2)
.
Satu lagi masalah yang harus diperhatikan, adalah yang toFixed()
dapat menghasilkan nol yang tidak perlu di akhir angka. Sebagai contoh:
var x=(23-7.37)
x
15.629999999999999
x.toFixed(6)
"15.630000"
Idenya adalah untuk membersihkan output menggunakan RegExp
:
function humanize(x){
return x.toFixed(6).replace(/\.?0*$/,'');
}
Yang RegExp
cocok dengan trailing nol (dan opsional titik desimal) untuk memastikan itu terlihat bagus untuk bilangan bulat juga.
humanize(23-7.37)
"15.63"
humanize(1200)
"1200"
humanize(1200.03)
"1200.03"
humanize(3/4)
"0.75"
humanize(4/3)
"1.333333"
var x = 0.3445434
x = Math.round (x*100) / 100 // this will make nice rounding
Ada masalah dengan semua solusi yang beredar menggunakan pengganda. Sayangnya, solusi kkyy dan Christoph salah.
Silakan uji kode Anda untuk nomor 551.175 dengan 2 tempat desimal - itu akan membulatkan ke 551.17 sementara itu harus 551.18 ! Tetapi jika Anda menguji mantan. 451.175 itu akan baik-baik saja - 451.18. Jadi sulit untuk menemukan kesalahan ini pada pandangan pertama.
Masalahnya adalah dengan mengalikan: coba 551.175 * 100 = 55117.49999999999 (ups!)
Jadi ide saya adalah memperlakukannya dengan toFixed () sebelum menggunakan Math.round ();
function roundFix(number, precision)
{
var multi = Math.pow(10, precision);
return Math.round( (number * multi).toFixed(precision + 1) ) / multi;
}
toFixed
terpengaruh juga - (0.335).toFixed(2) == 0.34 == (0.345).toFixed(2)
... Metode apa pun yang digunakan, lebih baik tambahkan epsilon sebelum pembulatan.
Kuncinya di sini saya kira adalah untuk mengumpulkan dengan benar terlebih dahulu, maka Anda dapat mengubahnya menjadi String.
function roundOf(n, p) {
const n1 = n * Math.pow(10, p + 1);
const n2 = Math.floor(n1 / 10);
if (n1 >= (n2 * 10 + 5)) {
return (n2 + 1) / Math.pow(10, p);
}
return n2 / Math.pow(10, p);
}
// All edge cases listed in this thread
roundOf(95.345, 2); // 95.35
roundOf(95.344, 2); // 95.34
roundOf(5.0364342423, 2); // 5.04
roundOf(0.595, 2); // 0.60
roundOf(0.335, 2); // 0.34
roundOf(0.345, 2); // 0.35
roundOf(551.175, 2); // 551.18
roundOf(0.3445434, 2); // 0.34
Sekarang Anda dapat dengan aman memformat nilai ini dengan toFixed (p). Jadi dengan kasus spesifik Anda:
roundOf(0.3445434, 2).toFixed(2); // 0.34
Jika Anda menginginkan string tanpa putaran, Anda dapat menggunakan RegEx ini (mungkin bukan cara yang paling efisien ... tetapi sangat mudah)
(2.34567778).toString().match(/\d+\.\d{2}/)[0]
// '2.34'
function trimNumber(num, len) {
const modulu_one = 1;
const start_numbers_float=2;
var int_part = Math.trunc(num);
var float_part = String(num % modulu_one);
float_part = float_part.slice(start_numbers_float, start_numbers_float+len);
return int_part+'.'+float_part;
}
return float_part ? int_part+'.'+float_part : int_part;
sebaliknya jika Anda melewati Integer, itu kembali nomor dengan titik di akhir (contoh masukan: 2100
, keluaran: 2100.
)
Mungkin Anda juga ingin pemisah desimal? Ini adalah fungsi yang baru saja saya buat:
function formatFloat(num,casasDec,sepDecimal,sepMilhar) {
if (num < 0)
{
num = -num;
sinal = -1;
} else
sinal = 1;
var resposta = "";
var part = "";
if (num != Math.floor(num)) // decimal values present
{
part = Math.round((num-Math.floor(num))*Math.pow(10,casasDec)).toString(); // transforms decimal part into integer (rounded)
while (part.length < casasDec)
part = '0'+part;
if (casasDec > 0)
{
resposta = sepDecimal+part;
num = Math.floor(num);
} else
num = Math.round(num);
} // end of decimal part
while (num > 0) // integer part
{
part = (num - Math.floor(num/1000)*1000).toString(); // part = three less significant digits
num = Math.floor(num/1000);
if (num > 0)
while (part.length < 3) // 123.023.123 if sepMilhar = '.'
part = '0'+part; // 023
resposta = part+resposta;
if (num > 0)
resposta = sepMilhar+resposta;
}
if (sinal < 0)
resposta = '-'+resposta;
return resposta;
}
Tidak ada cara untuk menghindari pembulatan yang tidak konsisten untuk harga dengan x.xx5 sebagai nilai aktual menggunakan perkalian atau pembagian. Jika Anda perlu menghitung harga yang benar di sisi klien, Anda harus menyimpan semua jumlah sen. Ini karena sifat representasi internal dari nilai numerik dalam JavaScript. Perhatikan bahwa Excel menderita masalah yang sama sehingga kebanyakan orang tidak akan melihat kesalahan kecil yang disebabkan oleh fenomena ini. Namun kesalahan dapat menumpuk setiap kali Anda menambahkan banyak nilai yang dihitung, ada teori keseluruhan tentang ini yang melibatkan urutan perhitungan dan metode lain untuk meminimalkan kesalahan dalam hasil akhir. Untuk menekankan pada masalah dengan nilai desimal, harap dicatat bahwa 0,1 + 0,2 tidak persis sama dengan 0,3 dalam JavaScript, sedangkan 1 + 2 sama dengan 3.
/** don't spend 5 minutes, use my code **/
function prettyFloat(x,nbDec) {
if (!nbDec) nbDec = 100;
var a = Math.abs(x);
var e = Math.floor(a);
var d = Math.round((a-e)*nbDec); if (d == nbDec) { d=0; e++; }
var signStr = (x<0) ? "-" : " ";
var decStr = d.toString(); var tmp = 10; while(tmp<nbDec && d*tmp < nbDec) {decStr = "0"+decStr; tmp*=10;}
var eStr = e.toString();
return signStr+eStr+"."+decStr;
}
prettyFloat(0); // "0.00"
prettyFloat(-1); // "-1.00"
prettyFloat(-0.999); // "-1.00"
prettyFloat(0.5); // "0.50"
Saya menggunakan kode ini untuk memformat pelampung. Ini didasarkan pada toPrecision()
tetapi strip nol yang tidak perlu. Saya akan menyambut saran untuk bagaimana menyederhanakan regex.
function round(x, n) {
var exp = Math.pow(10, n);
return Math.floor(x*exp + 0.5)/exp;
}
Contoh penggunaan:
function test(x, n, d) {
var rounded = rnd(x, d);
var result = rounded.toPrecision(n);
result = result.replace(/\.?0*$/, '');
result = result.replace(/\.?0*e/, 'e');
result = result.replace('e+', 'e');
return result;
}
document.write(test(1.2000e45, 3, 2) + '=' + '1.2e45' + '<br>');
document.write(test(1.2000e+45, 3, 2) + '=' + '1.2e45' + '<br>');
document.write(test(1.2340e45, 3, 2) + '=' + '1.23e45' + '<br>');
document.write(test(1.2350e45, 3, 2) + '=' + '1.24e45' + '<br>');
document.write(test(1.0000, 3, 2) + '=' + '1' + '<br>');
document.write(test(1.0100, 3, 2) + '=' + '1.01' + '<br>');
document.write(test(1.2340, 4, 2) + '=' + '1.23' + '<br>');
document.write(test(1.2350, 4, 2) + '=' + '1.24' + '<br>');