Javascript, toFixed satu desimal kecuali jika nilainya 0

Oct 09 2020

Saya perlu memperbaiki angka dengan desimal menjadi hanya 1 desimal, jadi saya mencoba ini:

const convert = (numberWithDecimal) => numberWithDecimal
  .toFixed(1)
  .replace('.', ',')
  .replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1.");

console.log(convert(123.123)); // "123,1" that's ok
console.log(convert(123.005)); // "123,0" that's NOT ok

Kode ada di sini: https://jsfiddle.net/pmiranda/sp0fLrhb/3/ Tapi, ketika desimal di-roun ke 0 saya tidak ingin menggunakannya, misalnya:

Dalam 123.005Saya perlu untuk mendapatkan 123, tidak123.0

Ada bantuan?

Jawaban

2 stevendesu Oct 09 2020 at 18:18

Seluruh tujuan dari .toFixedfungsi ini adalah untuk memastikan jumlah tempat desimal tetap , seperti saat menampilkan mata uang (Anda akan sering menampilkan$25.00 instead of $25)

Jika Anda tidak menginginkan angka desimal tetap (misalnya Anda terkadang menginginkan 0 dan terkadang ingin 1) maka Anda tidak ingin menggunakan .toFixed. Sebagai gantinya, coba gunakan perkalian dan pembulatan untuk mendapatkan hasil yang Anda inginkan:

const convert = (numberWithDecimal) => String(
        Math.round(numberWithDecimal * 10) / 10
    )
    .replace(".", ",");
console.log(convert(123.123));
console.log(convert(123.005));

Catatan menarik tentang kinerja

Saya suka ke profil solusi bila memungkinkan dan tampak sekilas seperti solusi saya akan lebih cepat (Aku hanya melakukan beberapa aritmatika integer sedangkan Anda melakukan beberapa fungsi string). Jadi saya menulis yang berikut ini:

var d0 = new Date();
for (var i = 0; i < 1000000; i++) { convert(123.123); }
console.log(new Date() - d0);

Saya kemudian menguji dua solusi kami. Di mesin saya, solusi Anda benar-benar berjalan sekitar 15% lebih cepat dari milik saya. Saya tidak tahu mengapa, tetapi jika Anda tertarik dengan kinerja maksimum maka solusi beberapa .replace()rantai Anda sebenarnya berjalan lebih cepat (di Firefox di Mac OS X)

Catatan 2 tentang kinerja

Jika Anda memilih untuk menggunakan Math.round()solusi tetapi ingin berjalan sedikit lebih cepat, ada peretasan dalam JavaScript untuk membulatkan angka dengan sangat cepat:

Math.round(123.123); // 123
Math.round(123.987); // 124

(123.123 + 0.5)|0; // 123
(123.987 + 0.5)|0; // 124

Perhatikan bahwa peretasan ini sebenarnya gagal dengan angka negatif. Tetapi selama Anda berurusan dengan bilangan positif, metode ini lebih cepat daripada menelepon Math.round()(dan kinerjanya hampir sama dengan solusi Anda

Ia bekerja karena operator bitwise dalam JavaScript ( &, |, ^, ~) hanya beroperasi pada bilangan bulat nilai-nilai. Jika diberikan non-integer, pertama-tama mereka akan memotong nilainya (memotong titik desimal apa pun). Karena kami ingin membulatkan dan tidak memotong, kami menambahkan 0,5 sebelum pemotongan.

1 imvain2 Oct 09 2020 at 18:17

Saya kira solusi sederhana yang jelas adalah menambahkan replace(',0','')rantai.

const convert = (numberWithDecimal) => numberWithDecimal
  .toFixed(1)
  .replace('.', ',')
  .replace(',0', '')
  .replace(/(\d)(?=(\d{3})+(?!\d))/g, "$1.");

console.log(convert(123.123)); // "123,1" that's ok
console.log(convert(123.005)); // "123,1" that's ok