Hapus angka nol yang tertinggal dari angka?

157

Sudahkah saya melewatkan panggilan API standar yang menghilangkan nol yang tertinggal dari nomor?

Ex.

var x = 1.234000 // to become 1.234;
var y = 1.234001; // stays 1.234001

Number.toFixed () dan Number.toPrecision () tidak cukup seperti yang saya cari.

Steven
sumber
6
Um 1.234000 === 1.234,.
Gumbo
5
Ya, jika Anda waspada (x) itu muncul tanpa angka nol
JKirchartz
50
Setelah bekerja dengan sejumlah klien, saya dapat bersaksi bahwa meskipun 1.234000 === 1.234, klien tidak ingin melihat angka nol tambahan jika mereka tidak perlu.
contactmatt
16
Gunakan parseFloat(n)?
Tn. Alien
Ini adalah solusi termudah yang mencakup semua kasus tepi bagi saya, terima kasih @ Mr.Alien.
James Perih

Jawaban:

140

Jika Anda mengonversinya menjadi string, string itu tidak akan menampilkan angka nol tambahan apa pun, yang tidak disimpan dalam variabel sejak pertama kali dibuat sebagai Angka, bukan String.

var n = 1.245000
var noZeroes = n.toString() // "1.245" 
Cristian Sanchez
sumber
6
Saya akan memposting beberapa kode untuk menghapus nol tetapi solusi Daniel tampaknya berhasil. Ia bahkan berfungsi untuk Strings seperti "1.2345000". ("1.2345000" * 1) .toString (); // menjadi 1.2345
Steven
7
Tentu saja, jika var Anda sudah menjadi string, Anda harus mengonversinya menjadi angka terlebih dahulu dan kemudian kembali lagi
derekcohen
Ini bekerja dengan baik. Saya mengalami masalah yang sama, mengkonversi float ke string dan kemudian parseFloat untuk mendapatkannya kembali dalam format yang tepat, hanya tanpa nol trailing.
Matt West
10
Ini bukan solusi lengkap. Ini tidak berfungsi ketika Anda memiliki variabel dengan beberapa kesalahan representasi floating point, seperti: var n = 1.245000000000001(dengan asumsi itu tidak signifikan untuk diwakili kepada pengguna)
tunjuk
7
Dapat menghasilkan hasil yang tidak terduga untuk angka-angka seperti: 1231111111111111111111111111111222222222222222222222222222222222222222222222222222.00. Representasi string akan berada dalam format eksponensial: 1.231111111111111e + 81
Stas Makutin
227

Saya memiliki contoh serupa di mana saya ingin menggunakan di .toFixed()mana perlu, tetapi saya tidak ingin padding padahal tidak. Jadi saya akhirnya menggunakan parseFloat bersamaan dengan toFixed.

toFixed tanpa bantalan

parseFloat(n.toFixed(4));

Opsi lain yang melakukan hal yang hampir sama.
Jawaban ini dapat membantu keputusan Anda

Number(n.toFixed(4));

toFixedakan membulatkan / menempelkan angka ke panjang tertentu, tetapi juga mengubahnya menjadi string. Mengubah itu kembali ke tipe numerik tidak hanya akan membuat angka lebih aman untuk digunakan secara aritmatika, tetapi juga secara otomatis menghapus setiap 0 yang tertinggal. Sebagai contoh:

var n = "1.234000";
    n = parseFloat(n);
 // n is 1.234 and in number form

Karena bahkan jika Anda menentukan angka dengan nol di belakangnya, angka itu dijatuhkan.

var n = 1.23000;
 // n == 1.23;
Gary
sumber
Perhatikan bahwa ini hanya berfungsi jika jumlah desimal yang relevan sama atau lebih besar dari argumen toFixed. Jika angkanya misalnya 1.200000 hasil toFixed (3) akan menjadi 1.200 dan dengan demikian, tidak semua nol trailing akan dihapus.
Leopoldo Sanczyk
@LeopoldoSanczyk Tidak, itu hanya benar jika Anda hanya menggunakan toFixed, karena mengembalikan string. Jenis angka secara otomatis kehilangan nol jejak. Itu sebabnya saya menggunakan keduanya bersama-sama.
Gary
@Gary, saya menarik komentar saya, saya telah melihat parseFloat(n).toFixed(4);bukannya jawaban Anda yang sebenarnya. Maafkan saya.
Leopoldo Sanczyk
2
Mengapa tidak +(n.toFixed(4))?
Константин Ван
3
terbalik! hanya satu masalah dengan jawaban Anda 0,00000005 dikonversi menjadi 5e-8 bagaimana saya bisa menghapus nol yang tidak signifikan tanpa masalah ini, saya bekerja dengan angka kecil seperti 0,000058000 di mana nol pada akhirnya perlu dihapus
PirateApp
29

Saya pertama kali menggunakan kombinasi jawaban matti-lyra dan gary:

r=(+n).toFixed(4).replace(/\.0+$/,'')

Hasil:

  • 1234870.98762341: "1234870.9876"
  • 1230009100: "1230009100"
  • 0,0012234: "0,0012"
  • 0,1200234: "0,12"
  • 0,000001231: "0"
  • 0,10001: "0,1000"
  • "asdf": "NaN" (jadi tidak ada kesalahan runtime)

Kasus yang agak bermasalah adalah 0,10001. Saya akhirnya menggunakan versi yang lebih panjang ini:

    r = (+n).toFixed(4);
    if (r.match(/\./)) {
      r = r.replace(/\.?0+$/, '');
    }
  • 1234870.98762341: "1234870.9876"
  • 1230009100: "1230009100"
  • 0,0012234: "0,0012"
  • 0,1200234: "0,12"
  • 0,000001231: "0"
  • 0,10001: "0,1"
  • "asdf": "NaN" (jadi tidak ada kesalahan runtime)

Pembaruan : Dan ini adalah versi terbaru Gary (lihat komentar):

r=(+n).toFixed(4).replace(/([0-9]+(\.[0-9]+[1-9])?)(\.?0+$)/,'$1')

Ini memberikan hasil yang sama seperti di atas.

w00t
sumber
1
Saya punya solusi regex murni yang saya yakini berfungsitoFixed(4).replace(/([0-9]+(\.[1-9]+)?)(\.?0+$)/,"$1")
Gary
1
Gah! Rupanya saya tidak sebagus memecahkan RegExes saya sendiri daripada yang lain. Saya tidak akan membiarkan ini mengalahkan saya! Saya menjalankan yang satu ini terhadap semua test case Anda ditambah (valid) yang dapat saya pikirkan([0-9]+(\.[0-9]+[1-9])?)(\.?0+$)
Gary
1
Regex adalah untuk rakus dan terkadang menghapus "0" dari bagian integer! :-( Kenapa tidak adil replace(/[,.][1-9]+(0+)/,'')?
Sebastian Sebald
1
Jawaban yang diremehkan ini.
Charlie
1
@ w00t Oh, maaf, saya mengerti sekarang. Saya adalah cara saya menguji ketika saya membuat milik saya (lihat tautan di atas). Milik Anda tidak gagal ketika Anda menggunakan toFixed, karena angka dijamin memiliki titik, tetapi gagal dalam pengujian saya karena saya ingin regex bekerja untuk angka apa pun, termasuk bilangan bulat tanpa titik. Tanpa toFixed, ia makan nol di akhir. Salahku.
geekley
22

The toFixedMetode akan melakukan pembulatan sesuai jika diperlukan. Ini juga akan menambahkan nol trailing, yang tidak selalu ideal.

(4.55555).toFixed(2);
//-> "4.56"

(4).toFixed(2);
//-> "4.00"

Jika Anda memasukkan nilai kembali ke angka, angka nol yang tertinggal tersebut akan turun. Ini adalah pendekatan yang lebih sederhana daripada melakukan pembulatan atau penghentian matematika Anda sendiri.

+(4.55555).toFixed(2);
//-> 4.56

+(4).toFixed(2);
//-> 4
CJ
sumber
1
rumit, tapi persis apa yang saya cari: menghapus nol trailing yang signifikan (yang tentu saja kami buat signifikan melalui toFixedpanggilan). itu kasus tepi UX yang aneh.
worc
12

Saya memiliki persyaratan yang pada dasarnya sama, dan menemukan bahwa tidak ada mekanisme bawaan untuk fungsi ini.

Selain memotong nol trailing, saya juga harus membulatkan dan memformat output untuk lokal pengguna saat ini (yaitu 123.456.789).

Semua pekerjaan saya tentang ini telah dimasukkan sebagai prettyFloat.js (Berlisensi MIT) di GitHub: https://github.com/dperish/prettyFloat.js


Contoh Penggunaan:

prettyFloat(1.111001, 3) // "1.111"
prettyFloat(1.111001, 4) // "1.111"
prettyFloat(1.1111001, 5) // "1.1111"
prettyFloat(1234.5678, 2) // "1234.57"
prettyFloat(1234.5678, 2, true) // "1,234.57" (en-us)


Diperbarui - Agustus 2018


Semua browser modern sekarang mendukung API Internasionalisasi ECMAScript , yang menyediakan perbandingan string yang peka bahasa, pemformatan angka, dan pemformatan tanggal dan waktu.

let formatters = {
    default: new Intl.NumberFormat(),
    currency: new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD', minimumFractionDigits: 0, maximumFractionDigits: 0 }),
    whole: new Intl.NumberFormat('en-US', { style: 'decimal', minimumFractionDigits: 0, maximumFractionDigits: 0 }),
    oneDecimal: new Intl.NumberFormat('en-US', { style: 'decimal', minimumFractionDigits: 1, maximumFractionDigits: 1 }),
    twoDecimal: new Intl.NumberFormat('en-US', { style: 'decimal', minimumFractionDigits: 2, maximumFractionDigits: 2 })
};

formatters.twoDecimal.format(1234.5678);  // result: "1,234.57"
formatters.currency.format(28761232.291); // result: "$28,761,232"

Untuk browser yang lebih lama, Anda dapat menggunakan polyfill ini: https://cdn.polyfill.io/v2/polyfill.min.js?features=Intl.~locale.en

dperish
sumber
Ini yang dicari. Anda harus membuat paket npm.
EnZo
Jadi saya mungkin harus memperbarui ini, karena ini sekarang dimungkinkan melalui API Internasionalisasi.
dperish
2
Ini sangat membantu, terima kasih untuk berbagi dan terima kasih untuk pembaruannya juga.
jaggedsoft
11

Bagaimana kalau hanya mengalikan dengan yang seperti ini?

var x = 1.234000*1; // becomes 1.234

var y = 1.234001*1; // stays as 1.234001
Howard
sumber
9

Anda dapat mencoba yang ini untuk mengurangi angka mengambang

var n = 0.0000;
n = parseFloat(n.toString()); 

//output n = 0; 
// n = 3.14000; --> n = 3.14;
Amit Panasara
sumber
7

Jawaban regex murni

n.replace(/(\.[0-9]*[1-9])0+$|\.0*$/,'$1');

Saya heran mengapa tidak ada yang memberi!

João Costa
sumber
Ini tidak akan berfungsi dengan angka (angka dinyatakan dalam pertanyaan asli). Saya suka solusi untuk representasi string!
BennyHilarious
6

Saya perlu menyelesaikan masalah ini juga ketika Django menampilkan nilai tipe desimal dalam bidang teks. Misalnya kapan '1' adalah nilainya. Itu akan menampilkan '1,00000000'. Jika '1.23' adalah nilainya, itu akan menampilkan '1.23000000' (Dalam kasus pengaturan 'decimal_places' dari 8)

Menggunakan parseFloat bukan pilihan bagi saya karena mungkin itu tidak mengembalikan nilai yang sama persis. toFixed bukan pilihan karena saya tidak ingin membulatkan apa pun, jadi saya membuat fungsi:

function removeTrailingZeros(value) {
    value = value.toString();

    # if not containing a dot, we do not need to do anything
    if (value.indexOf('.') === -1) {
        return value;
    }

    # as long as the last character is a 0 or a dot, remove it
    while((value.slice(-1) === '0' || value.slice(-1) === '.') && value.indexOf('.') !== -1) {
        value = value.substr(0, value.length - 1);
    }
    return value;
}
megasnort
sumber
Ini berfungsi, namun ini sangat tidak efisien, karena menghasilkan penciptaan beberapa string per eksekusi. Bayangkan menjalankan ini pada semua sel dalam sebuah tabel, di mana angka yang baik adalah 0,00000. Pilihan yang lebih baik adalah menentukan berapa banyak nol trailing di sana, lalu lakukan irisan sekaligus. Menentukan karakter apa, sebagian besar efisien, membelah string kurang begitu.
Derek Nigel Bartram
Saya melakukan sesuatu yang mirip dengan saran Anda Derek: github.com/rek/remove-trailing-zeros/blob/master/…
rekarnar
Tes perf ada di sini: jsperf.com/remove-trailing-zeros/1/1 , Anda benar, menemukan nol dan menghapusnya jauh lebih cepat!
rekarnar
4

Tak satu pun dari solusi ini bekerja untuk saya untuk jumlah yang sangat kecil. http://numeraljs.com/ memecahkan ini untuk saya.

parseFloat(0.00000001.toFixed(8));
// 1e-8

numeral(0.00000001).format('0[.][00000000]');
// "0.00000001"
Devon
sumber
Tidak dapat menangani lebih dari 6 presisi. Saya akan mengatakan perpustakaan ini tidak berguna jika dimaksudkan untuk jumlah kecil. Jelas tidak direkomendasikan.
Daniel Kmak
2

Jika Anda tidak dapat menggunakan Floats karena alasan apa pun (seperti float-uang yang terlibat) dan sudah mulai dari string yang mewakili angka yang benar, Anda dapat menemukan solusi ini berguna. Itu mengkonversi string yang mewakili angka ke string yang mewakili angka tanpa nol trailing.

function removeTrailingZeroes( strAmount ) {
    // remove all trailing zeroes in the decimal part
    var strDecSepCd = '.'; // decimal separator
    var iDSPosition = strAmount.indexOf( strDecSepCd ); // decimal separator positions
    if ( iDSPosition !== -1 ) {
        var strDecPart = strAmount.substr( iDSPosition ); // including the decimal separator

        var i = strDecPart.length - 1;
        for ( ; i >= 0 ; i-- ) {
            if ( strDecPart.charAt(i) !== '0') {
                break;
            }
        }

        if ( i=== 0 ) {
            return strAmount.substring(0, iDSPosition);
        } else {
            // return INTPART and DS + DECPART including the rightmost significant number
            return strAmount.substring(0, iDSPosition) + strDecPart.substring(0,i + 1);
        }
    }

    return strAmount;
}
BennyHilarious
sumber
0

Setelah membaca semua jawaban - dan komentar - saya berakhir dengan ini:

function isFloat(n) {
    let number = (Number(n) === n && n % 1 !== 0) ? eval(parseFloat(n)) : n;
    return number;
}

Saya tahu menggunakan evalbisa berbahaya, tetapi ini banyak membantu saya.

Begitu:

isFloat(1.234000);     // = 1.234;
isFloat(1.234001);     // = 1.234001
isFloat(1.2340010000); // = 1.234001

Jika Anda ingin membatasi tempat desimal, gunakan toFixed()seperti yang ditunjukkan orang lain.

let number = (Number(n) === n && n % 1 !== 0) ? eval(parseFloat(n).toFixed(3)) : n;

Itu dia.

ed1nh0
sumber
0

Saya perlu menghapus nol yang tertinggal tetapi menyimpan setidaknya 2 desimal, termasuk nol apa pun.
Angka yang saya kerjakan adalah 6 string angka desimal, dihasilkan oleh .toFixed (6).

Hasil yang diharapkan:

var numstra = 12345.000010 // should return 12345.00001
var numstrb = 12345.100000 // should return 12345.10
var numstrc = 12345.000000 // should return 12345.00
var numstrd = 12345.123000 // should return 12345.123

Larutan:

var numstr = 12345.100000

while (numstr[numstr.length-1] === "0") {           
    numstr = numstr.slice(0, -1)
    if (numstr[numstr.length-1] !== "0") {break;}
    if (numstr[numstr.length-3] === ".") {break;}
}

console.log(numstr) // 12345.10

Logika:

Jalankan fungsi loop jika karakter string terakhir adalah nol.
Hapus karakter terakhir dan perbarui variabel string.
Jika karakter terakhir string yang diperbarui bukan nol, akhiri.
Jika string yang diperbarui karakter ketiga hingga terakhir adalah titik apung, akhiri.

Kevin H.
sumber
-1

Inilah solusi yang mungkin:

var x = 1.234000 // to become 1.234;
var y = 1.234001; // stays 1.234001

eval(x) --> 1.234
eval(y) --> 1.234001
Bulan
sumber
4
Anda tidak perlu eval untuk tugas sederhana ini! parseFloat()akan jauh lebih tepat.
hutchbat
6
eval == evil Jangan pernah menggunakannya
eagor