Como posso encontrar o comprimento de um número?

161

Estou procurando obter o tamanho de um número em JavaScript ou jQuery?

Tentei value.lengthsem sucesso. Preciso converter isso em uma string primeiro?

Code Junkie
fonte
3
Sim, converta-o em uma string. O conceito de "comprimento" de um número só é significativo em termos de algum esquema de representação numérica.
Pointy
Sim, você precisa converter primeiro a string, IE (1234) .toString (). Length
Osama Bari
Benchmarks para as 3 principais respostas: mensurathat.net/Benchmarks/ShowResult/92276
Richie Bendall

Respostas:

304
var x = 1234567;

x.toString().length;

Este processo também funcionará para Float Numbere para Exponential numbertambém.

thecodeparadox
fonte
9
Marcou com +1. Caso não seja óbvio para ninguém, o ponto decimal nos flutuadores será contado no comprimento da string. . por exemplo 2.5.toString () comprimento saídas 3.
dading84
1
@ dading84: Eu acho Math.floor () iria corrigir isso: Math.floor (99,5454) .ToString () comprimento === 2.
Manfred
7
Esta solução não funcionaria com um número grande ou pequeno com mais de 20 dígitos. por exemplo. 1.2e + 22 toString (). Comprimento saídas 7
CherylG 18/16/16
Observe também que isso é extremamente lento. Fiz um teste no nó e verifica-se que é mais de 1200% mais lento que o Arturs respondeu.
Oliver Dixon
1
Não é uma boa solução, por exemplo: const val = 0295; const x = val.toString (). length; console.log (x) // a saída é: 3
karolkarp
82

Ok, muitas respostas, mas essa é pura matemática, apenas por diversão ou por lembrar que a matemática é importante:

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

Na verdade, isso fornece o "comprimento" do número, mesmo que esteja na forma exponencial. numdeve ser um número inteiro não negativo aqui: se for negativo, pegue seu valor absoluto e ajuste o sinal posteriormente.

Atualização para ES2015

Agora isso Math.log10é uma coisa , você pode simplesmente escrever

const len = Math.ceil(Math.log10(num + 1));
MaxArt
fonte
1
Eu acho que esse de matemática pura é mais eficiente / mais rápido.
Noitidart 15/02/14
2
Awesme perf homem obrigado. Os resultados que obtive mostram que a matemática é rápida, é esse o resultado que você obteve? Aqui está o meu resultado: i.imgur.com/9BKxyd3.png
Noitidart 7/14
1
@HubertGrzeskowiak Oh isso é bom. Vejo que esse método é basicamente um método matemático, mas com alguns hacks rápidos. Ele deixa cair um Math.ceile usa um mais rápido Math.abs. Mas sinceramente não esperava esse ganho de desempenho no Chrome ... É bom saber!
MaxArt
3
Perfeito, mas dá 0 se o número for 0, em vez disso 1
StateLess
1
No 1e + 16 ou mais dá 1 a menos, então 10000000000000000 retornos 16 em vez de 17 e assim por diante ...
Goty metal
12

Eu tenho usado essa funcionalidade no node.js, esta é a minha implementação mais rápida até agora:

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

Ele deve manipular números inteiros positivos e negativos (também na forma exponencial) e deve retornar o comprimento da parte inteira em números flutuantes.

A referência a seguir deve fornecer algumas dicas sobre o método: Weisstein, Eric W. "Number Length". De MathWorld - um recurso da Web da Wolfram.

Acredito que alguma operação bit a bit possa substituir o Math.abs, mas o jsperf mostra que o Math.abs funciona bem na maioria dos mecanismos js.

Atualização : conforme observado nos comentários, esta solução tem alguns problemas :(

Atualização2 (solução alternativa) : acredito que, em algum momento, surjam problemas de precisão e os que Math.log(...)*0.434...se comportam inesperadamente. No entanto, se os dispositivos Internet Explorer ou Mobile não forem sua xícara de chá, você poderá substituir esta operação pela Math.log10função No Node.js, escrevi um teste básico rápido com a função nLength = (n) => 1 + Math.log10(Math.abs(n) + 1) | 0;e com Math.log10ela funcionou conforme o esperado. Observe que Math.log10não é universalmente suportado.

Israfil Havilah
fonte
Como curiosidade eu tenho realizado um método JSPerf com nLength vs toString () comprimento sobre este ..... Jsperf.com/convert-number-to-string-and-get-length/2
Israfil Havilah
Haha, essa é basicamente a solução que eu forneci! Eu não tinha ideia de que poderia ter um desempenho tão bom.
MaxArt
2
Sinto muito, eu disse algo sobre eu inventar a solução ou algo assim? Por que você não lê atentamente antes de postar? Aliás, o algoritmo foi descoberto muito antes de Steven Wolfram nascer, e mesmo assim a página que você vinculou não fornece uma solução em Javascript. Eu fiz, 9 meses antes de você.
MaxArt
1
O "+1" deve ser provavelmente fora da chamada Math.abs: Math.log (Math.abs (n) + 1) ...
Hubert Grzeskowiak
1
No 1e + 16 ou mais dá 1 a menos, então 10000000000000000 retornos 16 em vez de 17 e assim por diante ...
Goty metal
11

Você deve fazer o número para string, a fim de levar o comprimento

var num = 123;

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

ou

alert(num.toString().length);
Adil
fonte
9

Também pode usar uma sequência de modelos:

const num = 123456
`${num}`.length // 6
funador
fonte
esta é a única resposta que funciona para mim porque conto um número que começa com 0.
jessiPP
5

Bem, sem converter o número inteiro em uma string, você pode criar um loop funky:

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

alert(length);​

Demonstração: http://jsfiddle.net/maniator/G8tQE/

Naftali tcp Neal
fonte
3
@ Pointy sim, isso está assumindo um número inteiro. Mesmo se você criar uma string, ela incluirá .como parte do cálculo.
Naftali aka Neal,
Sim, mas é uma questão filosófica interessante se o ponto deve ser incluído no "comprimento" :-)
Pointy
4

Primeiro converta-o em uma string:

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

Adicionar uma string vazia a ela implicitamente fará mynumbercom que ela se transforme em uma string.

tskuzzy
fonte
1
Não funciona com exponenciais como 1e + 16 que retorna 5.
Goty metal
4

Existem três maneiras de fazer isso.

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

melhor desempenho um (melhor desempenho no ie11)

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

Math (melhor desempenho no Chrome, Firefox, mas o mais lento no ie11)

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

existe um jspref aqui http://jsperf.com/fastest-way-to-get-the-first-in-a-number/2

Eric Chen
fonte
4

Você deve optar pelo mais simples (stringLength), a legibilidade sempre supera a velocidade. Mas se você se preocupa com velocidade, aqui estão alguns abaixo.

Três métodos diferentes, todos com velocidade variável.

// 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);
}
Oliver Dixon
fonte
3

Fiz uma pergunta semelhante em um teste.

Encontre o comprimento de um número sem converter em string

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 ]

Números negativos foram adicionados para complicar um pouco mais, daí o Math.abs ().

Adrian Lynch
fonte
2

Gostaria de corrigir a resposta do @Neal, que era bastante boa para números inteiros, mas o número 1 retornaria um comprimento de 0 no caso anterior.

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;
}
Gregzenegair
fonte
0

Tente o seguinte:

$("#element").text().length;

Exemplo disso em uso

Matthew Riches
fonte
0

Sim, você precisa converter em string para encontrar o comprimento.

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.
Kamal
fonte