Bir sayının uzunluğunu nasıl bulabilirim?


161

JavaScript veya jQuery bir sayı uzunluğunu almak için mi arıyorsunuz?

Ben value.lengthherhangi bir başarı olmadan denedim , önce bir dizeye dönüştürmek gerekiyor mu?


3
Evet, dizeye dönüştür. Bir sayının "uzunluk" kavramı, sadece bir sayı temsil şeması açısından anlamlıdır.
Sivri

Evet, önce dizeye dönüştürmeniz gerekiyor, IE (1234) .toString (). Uzunluk
Osama Bari

Yanıtlar:


304
var x = 1234567;

x.toString().length;

Bu süreç aynı zamanda Float Numberve aynı zamanda da çalışacaktır Exponential number.


9
+ 1'lediğini. Kimsenin belli olmadığı durumlarda, kayan noktalardaki ondalık nokta dize uzunluğunda sayılır. 2.5.toString (). uzunluk çıkışları 3.
dading84

1
@ dading84: Sanırım Math.floor () bunu düzeltir: Math.floor (99.5454) .toString (). uzunluk === 2
Manfred

7
Bu çözüm, 20 basamaktan fazla olan çok sayıda veya az sayıda çalışmaz. Örneğin. 1.2e + 22 toString (). Uzunluk çıkışları 7
CherylG 18:16 '

Ayrıca bunun son derece yavaş olduğuna dikkat edin. Düğümde bir test yaptım ve Arturs'ın cevabından% 1200'den daha yavaş olduğu ortaya çıktı.
Oliver Dixon

1
İyi bir çözüm değildir, örnek: const val = 0295; const x = val.toString (). uzunluk; console.log (x) // çıktı: 3
karolkarp

82

Tamam, çok fazla cevap var, ama bu sadece eğlence için veya Math'ın Önemli olduğunu hatırlamak için saf bir matematiktir:

var len = Math.ceil(Math.log(num + 1) / Math.LN10);

Bu, üstel formda olsa bile, sayının "uzunluğunu" verir. numburada negatif olmayan bir tamsayı olması gerekiyordu: negatifse, mutlak değerini alın ve daha sonra işareti ayarlayın.

ES2015 Güncellemesi

Şimdi bu Math.log10bir şey , sadece yazabilirsiniz

const len = Math.ceil(Math.log10(num + 1));

1
bu saf matematik biri en verimli / hızlı olduğunu düşünüyorum.
Noitidart

2
Awesme perf adam teşekkürler. Aldığım sonuçlar matematik yolunun fastet olduğunu gösteriyor, elde ettiğiniz sonuç bu mu? işte sonuç: i.imgur.com/9BKxyd3.png
Noitidart

1
@HubertGrzeskowiak Oh bu güzel. Bu yöntemin temelde bir matematik yöntemi olduğunu görüyorum, ancak bazı hız kesmekle. A düşer Math.ceilve daha hızlı Math.abskullanır. Ama dürüst olmak gerekirse, Chrome'daki performans artışını beklemiyordum ... Bilmek güzel!
MaxArt

3
Mükemmel, ama senin yerine 0 ise 0 verir 1
StateLess

1
1e + 16 veya daha fazlasında 1 daha az verir, bu yüzden 10000000000000000 17 yerine 16 döndürür ...
Goty Metal

12

Bu işlevselliği node.js'de kullanıyorum, şu ana kadarki en hızlı uygulamanız:

var nLength = function(n) { 
    return (Math.log(Math.abs(n)+1) * 0.43429448190325176 | 0) + 1; 
}

Pozitif ve negatif tamsayıları (üstel formda da) işlemeli ve şamandıralarda tamsayı kısmının uzunluğunu döndürmelidir.

Aşağıdaki referans, yönteme ilişkin bazı bilgiler sağlamalıdır: Weisstein, Eric W. "Sayı Uzunluğu". From WolfWorld - Bir Wolfram Web Kaynağı.

Bazı bitsel işlemlerin Math.abs'ın yerini alabileceğine inanıyorum, ancak jsperf, Math.abs'ın js motorlarının çoğunda gayet iyi çalıştığını gösteriyor.

Güncelleme : Yorumlarda belirtildiği gibi, bu çözümün bazı sorunları var :(

Güncelleme2 (geçici çözüm) : Bir noktada hassaslık sorunlarının ortaya çıktığını ve Math.log(...)*0.434...sadece beklenmedik bir şekilde davrandığını düşünüyorum. Bununla birlikte, Internet Explorer veya Mobil cihazlar çayınız değilse, bu işlemi Math.log10işlevle değiştirebilirsiniz. Node.js'de fonksiyonla hızlı bir temel test yazdım nLength = (n) => 1 + Math.log10(Math.abs(n) + 1) | 0;ve Math.log10beklendiği gibi çalıştı. Math.log10Evrensel olarak desteklenmediğini lütfen unutmayın .


Merak olarak ben bu konuda nLength yöntemi vs toString () ile bir JsPerf yaptım .... jsperf.com/convert-number-to-string-and-get-length/2
Israfil Havilah

Haha, temelde sağladığım çözüm! Çok iyi performans gösterebileceğine dair hiçbir fikrim yoktu.
MaxArt

2
Özür dilerim, çözümü icat ettiğim gibi bir şey mi söyledim yoksa böyle bir şey mi? Göndermeden önce neden dikkatlice okumuyorsun? Konuyla ilgili, Steven Wolfram daha doğmadan algorhythm yolu keşfedildi ve yine sen bağlantılı sayfa yok değil JavaScript bir çözüm sağlar. Senden 9 ay önce yaptım.
MaxArt

1
"+1" muhtemelen Math.abs çağrısının dışında olmalıdır: Math.log (Math.abs (n) + 1) ...
Hubert Grzeskowiak

1
1e + 16 veya daha fazlasında 1 daha az verir, bu yüzden 10000000000000000 17 yerine 16 döndürür ...
Goty Metal

11

Uzunluk almak için dizgiye sayı yapmak zorundasınız

var num = 123;

alert((num + "").length);

veya

alert(num.toString().length);

9

Bir şablon dizesi de kullanılabilir:

const num = 123456
`${num}`.length // 6

Bu benim için çalışan tek cevap çünkü 0 ile başlayan bir sayı sayıyorum.
jessiPP

5

Tamsayıyı bir dizeye dönüştürmeden korkak bir döngü yapabilirsiniz:

var number = 20000;
var length = 0;
for(i = number; i > 1; ++i){
     ++length;
     i = Math.floor(i/10);
}

alert(length);​

Demo: http://jsfiddle.net/maniator/G8tQE/


3
@Pointy evet, bu bir tamsayı varsayar . Bir dize yapsanız bile ., hesaplamanın bir parçası olarak.
Naftali aka Neal

Evet, ilginç bir felsefi soru olsa da, noktanın "uzunluğa" dahil edilmesi gerekip gerekmediği :-)
Pointy

4

İlk önce bir dizeye dönüştürün:

var mynumber = 123;
alert((""+mynumber).length);

Buraya boş bir dize eklemek dolaylı mynumberolarak bir dizeye dönüşmeye neden olur .


1
5 döndüren 1e + 16 gibi
üslerle çalışmaz

4

Bunu yapmanın üç yolu var.

var num = 123;
alert(num.toString().length);

daha iyi bir performans (ie11'de en iyi performans)

var num = 123;
alert((num + '').length);

Math (Chrome'da en iyi performans, firefox ancak ie11'de en yavaş)

var num = 123
alert(Math.floor( Math.log(num) / Math.LN10 ) + 1)

burada bir jspref var http://jsperf.com/fastest-way-to-get-the-first-in-a-number/2


4

En basit olanı (stringLength) seçmelisiniz, okunabilirlik her zaman hızı aşıyor. Ama hızı önemsiyorsanız, aşağıda bazılarını bulabilirsiniz.

Değişen hızda üç farklı yöntem.

// 34ms
let weissteinLength = function(n) { 
    return (Math.log(Math.abs(n)+1) * 0.43429448190325176 | 0) + 1;
}

// 350ms
let stringLength = function(n) {
    return n.toString().length;
}

// 58ms
let mathLength = function(n) {
    return Math.ceil(Math.log(n + 1) / Math.LN10);
}

// Simple tests below if you care about performance.

let iterations = 1000000;
let maxSize = 10000;

// ------ Weisstein length.

console.log("Starting weissteinLength length.");
let startTime = Date.now();

for (let index = 0; index < iterations; index++) {
    weissteinLength(Math.random() * maxSize);
}

console.log("Ended weissteinLength length. Took : " + (Date.now() - startTime ) + "ms");


// ------- String length slowest.

console.log("Starting string length.");
startTime = Date.now();

for (let index = 0; index < iterations; index++) {
    stringLength(Math.random() * maxSize);
}

console.log("Ended string length. Took : " + (Date.now() - startTime ) + "ms");


// ------- Math length.

console.log("Starting math length.");
startTime = Date.now();

for (let index = 0; index < iterations; index++) {
    mathLength(Math.random() * maxSize);
}

3

Bir testte de benzer bir soru sordum.

Dizeye dönüştürmeden bir sayının uzunluğunu bulma

const numbers = [1, 10, 100, 12, 123, -1, -10, -100, -12, -123, 0, -0]

const numberLength = number => {

  let length = 0
  let n = Math.abs(number)

  do {
    n /=  10
    length++
  } while (n >= 1)

  return length
}

console.log(numbers.map(numberLength)) // [ 1, 2, 3, 2, 3, 1, 2, 3, 2, 3, 1, 1 ]

Negatif sayılar biraz daha karmaşık hale getirmek için eklenmiştir, bu nedenle Math.abs ().


2

Tamsayılar için oldukça iyi olan @Neal cevabını düzeltmek istiyorum, ancak 1 sayısı önceki durumda 0 uzunluğunu döndürür.

function Longueur(numberlen)
{
    var length = 0, i; //define `i` with `var` as not to clutter the global scope
    numberlen = parseInt(numberlen);
    for(i = numberlen; i >= 1; i)
    {
        ++length;
        i = Math.floor(i/10);
    }
    return length;
}


0

Evet, uzunluğu bulmak için dizeye dönüştürmeniz gerekir.

var x=100;// type of x is number
var x=100+"";// now the type of x is string
document.write(x.length);//which would output 3.
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.