Bir sayıdan önemsiz sondaki sıfırlar kaldırılsın mı?


157

Sondaki önemsiz sıfırları bir sayıdan kaldıran standart bir API çağrısını kaçırdım mı?

Ör.

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

Number.toFixed () ve Number.toPrecision () aradığım şey değil.


6
Um 1.234000 === 1.234.
Gumbo

5
Evet, uyarı (x) yaparsanız, sondaki sıfırlar olmadan açılır
JKirchartz

50
Birkaç müşteriyle çalıştıktan sonra, 1.234000 === 1.234 olsa da, müşterilerin ihtiyaç duymadıklarında bu ekstra sıfırları görmek istemediğini ifade edebilirim.
contactmatt

16
Kullan parseFloat(n)?
Bay Alien

Bu benim için tüm son vakaları kapsayan en kolay çözümdü, teşekkürler Mr.Alien.
James Perih

Yanıtlar:


140

Bir dizgeye dönüştürürseniz, Dize olarak değil Sayı olarak oluşturulduğundan bu yana değişkente ilk sırada depolanmayan herhangi bir sıfır göstermez.

var n = 1.245000
var noZeroes = n.toString() // "1.245" 

6
Sıfırları ayırmak için bazı kodlar göndermek üzereydim ama Daniel'in çözümü işe yarıyor gibi görünüyor. Hatta "1.2345000" gibi Dizeler için bile çalışır. ("1.2345000" * 1) .toString (); // 1.2345
Steven

7
Tabii ki, var zaten bir dize ise, önce bir sayıya ve daha sonra tekrar bir sayıya dönüştürmeniz gerekir
derekcohen

Bu harika çalıştı. Ben aynı sorunu sahip, kayan dize ve daha sonra sadece sondaki sıfırlar olmadan, doğru biçimde geri almak için parseFloat dönüştürdü.
Matt West

10
Bu tam bir çözüm değil. Kayan nokta gösterim hatası olan bir değişkeniniz olduğunda işe yaramaz, örneğin: var n = 1.245000000000001(kullanıcıya temsil edilmesinin önemsiz olduğu varsayılarak)
Ağustos

7
Aşağıdaki gibi sayılar için beklenmedik sonuçlar üretebilir: 123111111111111111111111111111122222222222222222222222222222222222222222222222222222.00. Dize temsili üstel biçimde olacaktır: 1.231111111111111e + 81
Stas Makutin

227

.toFixed()Gerektiğinde kullanmak istediğim yerde benzer bir örneğim vardı , ancak dolgu olmadığında istemedim. Bu yüzden parseFloat'ı toFixed ile birlikte kullandım.

Dolgu olmadan sabitlenmiş

parseFloat(n.toFixed(4));

Neredeyse aynı şeyi yapan başka bir seçenek
Bu cevap kararınıza yardımcı olabilir

Number(n.toFixed(4));

toFixedsayıyı belirli bir uzunluğa yuvarlar / doldurur, ancak bir dizeye dönüştürür. Bunu sayısal bir türe geri dönüştürmek, sayıyı aritmetik olarak kullanmak için daha güvenli hale getirmekle kalmaz, aynı zamanda arkadaki 0'ları otomatik olarak düşürür. Örneğin:

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

Çünkü sondaki sıfırlarla bir sayı tanımlasanız bile bunlar bırakılır.

var n = 1.23000;
 // n == 1.23;

Bunun yalnızca ilgili ondalık sayıların toFixed bağımsız değişkenine eşit veya daha büyük olması durumunda işe yaradığını unutmayın. Sayı örneğin 1.200000 ise, toFixed (3) 'ün sonucu 1.200 olur ve bu nedenle sondaki sıfırlar kaldırılmaz.
Leopoldo Sanczyk

@LeopoldoSanczyk Hayır, bu yalnızca toFixed kullanıyorsanız doğrudur, çünkü bir dize döndürür. Sayı türleri otomatik olarak arkadaki sıfırları kaybeder. Bu yüzden ikisini birlikte kullandım.
Gary

@ Gary, yorumumu geri çekiyorum, parseFloat(n).toFixed(4);gerçek cevabın yerine gördüm . Üzgünüm.
Leopoldo Sanczyk

2
Neden olmasın +(n.toFixed(4))?
Константин Ван

3
upvoted! Cevabınızla ilgili tek bir sorun 0.00000005 5e-8'e dönüştürülür.Bu sorun olmadan önemsiz sıfırları nasıl kaldırabilirim, sonunda sıfırların kaldırılması gereken
0.000058000

29

İlk olarak matti-lyra ve gary'nin cevaplarının bir kombinasyonunu kullandım:

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

Sonuçlar:

  • 1234870.98762341: "1234870.9876"
  • 1230009100: "1230009100"
  • 0.0012234: "0.0012"
  • 0.1200234: "0.12"
  • 0.000001231: "0"
  • 0.10001: "0.1000"
  • "asdf": "NaN" (yani çalışma zamanı hatası yok)

Biraz sorunlu olan durum 0.10001'dir. Bu uzun sürümü kullanarak sona erdi:

    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" (yani çalışma zamanı hatası yok)

Güncelleme : Ve bu Gary'nin yeni sürümü (yorumlara bakın):

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

Bu, yukarıdaki ile aynı sonuçları verir.


1
toFixed(4).replace(/([0-9]+(\.[1-9]+)?)(\.?0+$)/,"$1")
Gary

1
Gah! Görünüşe göre kendi RegExes'imi kırma konusunda diğerlerinden daha iyi değilim. Bunun beni dövmesine izin vermeyeceğim! Bunu tüm test durumlarınıza ve aklınıza gelebilecek herhangi bir (geçerli) karşı çalıştırdım([0-9]+(\.[0-9]+[1-9])?)(\.?0+$)
Gary

1
Regex açgözlü bir bazen bir "0" tamsayı bölümünden kaldırır! :-( Neden sadece replace(/[,.][1-9]+(0+)/,'')?
Sebastian Sebald

1
Yetersiz cevap bu.
Charlie

1
@ w00t Oh, üzgünüm, şimdi anlıyorum. Benim yaptığım zaman test ettiğim yöntem buydu (yukarıdaki bağlantıya bakınız). ToFixed'i kullandığınızda sizinki başarısız olmaz, çünkü sayının bir noktaya sahip olması garanti edilir, ancak testlerimde başarısız oluyordu çünkü regex'in nokta içermeyen tamsayılar da dahil olmak üzere herhangi bir sayı için çalışmasını istedim. Sabitlenmiş olmadan, sonunda sıfır yer. Benim hatam.
geekley

22

toFixedGerekirse yönteminin uygun yuvarlama yapacağız. Ayrıca her zaman ideal olmayan arka sıfırlar ekleyecektir.

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

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

Dönüş değerini bir sayıya çevirirseniz, bu sıfırlar atılır. Bu kendi yuvarlama veya kesme matematik yapmaktan daha basit bir yaklaşımdır.

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

+(4).toFixed(2);
//-> 4

1
zor, ama tam olarak ben ne aradığını: önemli sondaki sıfırlar (ki tabii ki toFixedçağrı yoluyla önemli hale) kaldırma . garip bir UX kenar çantası.
worc

12

Temelde aynı gereksinime sahiptim ve bu işlevsellik için yerleşik bir mekanizma olmadığını buldum.

Sondaki sıfırları kırpmaya ek olarak, kullanıcının geçerli yerel ayarının çıktısını da yuvarlama ve biçimlendirme ihtiyacım vardı (yani 123,456.789).

Bu konudaki tüm çalışmalarım GitHub'da prettyFloat.js (MIT Lisanslı) olarak dahil edildi: https://github.com/dperish/prettyFloat.js


Kullanım örnekleri:

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)


Güncellendi - Ağustos, 2018


Tüm modern tarayıcılar artık dile duyarlı dize karşılaştırma, sayı biçimlendirme ve tarih ve saat biçimlendirme sağlayan ECMAScript Uluslararasılaştırma API'sını desteklemektedir .

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"

Daha eski tarayıcılar için bu çoklu dolguyu kullanabilirsiniz: https://cdn.polyfill.io/v2/polyfill.min.js?features=Intl.~locale.tr


Arayan buydu. Bir npm paketi oluşturmanız gerekir.
EnZo

Bu yüzden muhtemelen bunu güncellemeliyim, çünkü bu artık Uluslararasılaştırma API'sı aracılığıyla mümkün.
dperish

2
Bu çok faydalı, paylaşım için teşekkürler ve güncelleme için teşekkürler.
jaggedsoft

11

Böyle biriyle çarpmaya ne dersiniz?

var x = 1.234000*1; // becomes 1.234

var y = 1.234001*1; // stays as 1.234001

9

Kayan sayıları küçültmek için bunu deneyebilirsiniz

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

//output n = 0; 
// n = 3.14000; --> n = 3.14;

7

Saf normal cevap

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

Acaba neden kimse bir tane vermedi!


Sayılarla çalışmaz (sayılar orijinal soruda belirtilir). Ben bir dize temsil çözüm olsa seviyorum!
BennyHilarious

6

Django bir metin alanında Ondalık türü değerleri görüntülerken de bu sorunu çözmek gerekiyordu. Örneğin '1' değerdi. '1.00000000' gösterecektir. '1.23' değer olsaydı, '1.23000000' değerini gösterir ('ondalık_yerleri' ayarının 8 olması durumunda)

Aynı değeri döndürmemesi mümkün olduğundan parseFloat kullanmak benim için bir seçenek değildi. Bir şey yuvarlamak istemediğim için toFixed bir seçenek değildi, bu yüzden bir işlev oluşturdum:

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;
}

Ancak bu işe yarıyor, çünkü yürütme başına birden çok dize oluşturulmasına neden oluyor. Bunu, iyi bir sayının .00000 olduğu bir tablodaki tüm hücrelerde çalıştırdığınızı düşünün. Daha iyi bir seçenek, kaç tane sıfırın olduğunu belirlemek, sonra dilimi tek seferde yapmak olacaktır. Bir karakterin ne olduğunu belirlemek büyük ölçüde etkilidir, dizeleri bölmek daha azdır.
Derek Nigel Bartram

Önerinize benzer bir şey yaptım Derek: github.com/rek/remove-trailing-zeros/blob/master/…
rekarnar

Mükemmel test burada: jsperf.com/remove-trailing-zeros/1 , haklısınız, sıfırları bulmak ve kaldırmak çok daha hızlı!
rekarnar

4

Bu çözümlerin hiçbiri benim için çok az sayıda işe yaramadı. http://numeraljs.com/ bunu benim için çözdü.

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

numeral(0.00000001).format('0[.][00000000]');
// "0.00000001"

6'dan fazla hassasiyetle çalışamaz. Bu kütüphane, küçük sayılar için kullanılıyorsa işe yaramaz diyebilirim. Kesinlikle tavsiye edilmez.
Daniel Kmak

2

Floats'ı herhangi bir nedenden dolayı kullanamazsanız (dahil olan para şamandıraları gibi) ve doğru sayıyı temsil eden bir dizeden başlıyorsanız, bu çözümü kullanışlı bulabilirsiniz. Bir sayıyı temsil eden bir dizeyi, sıfır içermeyen sayıyı temsil eden bir dizeye dönüştürür.

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;
}

0

Tüm cevapları ve yorumları okuduktan sonra bununla sonuçlandım:

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

Kullanmayı biliyorum eval şekilde zararlı olabileceğini ama bu bana çok yardımcı oldu.

Yani:

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

Ondalık basamakları sınırlamak istiyorsanız, toFixed()diğerlerinin işaret ettiği gibi kullanın .

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

Bu kadar.


0

Sondaki sıfırları kaldırmam gerekiyordu, ancak sıfırlar dahil en az 2 ondalık sayı tutmam gerekiyordu .
Üzerinde çalıştığım sayılar .toFixed (6) tarafından oluşturulan 6 ondalık sayı dizesidir.

Beklenen Sonuç:

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

Çözüm:

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

Mantık:

Dize son karakteri sıfır ise döngü işlevini çalıştırın.
Son karakteri kaldırın ve dize değişkenini güncelleyin.
Güncellenen dize son karakteri sıfır değilse, bitiş döngüsü.
Üçüncü karakterden son karaktere kadar güncellenen dize bir kayan nokta ise, bitiş döngüsü.


-1

İşte olası bir çözüm:

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

eval(x) --> 1.234
eval(y) --> 1.234001

4
Bu basit görev için eval'e ihtiyacınız yok! parseFloat()çok uygun olacak.
hutchbat

6
eval == kötülük. Hiç kullanma
eagor
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.