Comment puis-je trouver la longueur d'un nombre?

161

Je cherche à obtenir la longueur d'un nombre en JavaScript ou jQuery?

J'ai essayé value.lengthsans succès, dois-je d'abord convertir cela en chaîne?

Accro au code
la source
3
Oui, convertissez-le en chaîne. Le concept de "longueur" d'un nombre n'a de sens qu'en termes d'un certain schéma de représentation des nombres.
Pointy
Oui, vous devez d'abord convertir en chaîne, IE (1234) .toString (). Length
Osama Bari
Benchmarks pour les 3 premières réponses: mesurethat.net/Benchmarks/ShowResult/92276
Richie Bendall

Réponses:

304
var x = 1234567;

x.toString().length;

Ce processus fonctionnera également pour Float Numberet pour Exponential numberaussi.

thecodeparadox
la source
9
+1. Au cas où cela ne serait évident pour personne, la virgule décimale en flottants sera comptée dans la longueur de la chaîne. par exemple 2.5.toString (). length sorties 3.
dading84
1
@ dading84: je suppose que Math.floor () corrigerait cela: Math.floor (99.5454) .toString (). length === 2
Manfred
7
Cette solution ne fonctionnerait pas avec un grand nombre ou un petit nombre de plus de 20 chiffres. par exemple. 1.2e + 22 toString (). Length sorties 7
CherylG
A noter également que c'est extrêmement lent. J'ai fait un test dans node et il s'avère que c'est plus de 1200% plus lent que la réponse d'Arturs.
Oliver Dixon
1
Ce n'est pas une bonne solution, exemple: const val = 0295; const x = val.toString (). length; console.log (x) // la sortie est: 3
karolkarp
82

Ok, tant de réponses, mais c'est une question de mathématiques pures, juste pour le plaisir ou pour se rappeler que les mathématiques sont importantes:

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

Cela donne en fait la "longueur" du nombre même s'il est sous forme exponentielle. numest censé être un entier non négatif ici: s'il est négatif, prenez sa valeur absolue et ajustez le signe par la suite.

Mise à jour pour ES2015

Maintenant que Math.log10c'est une chose , tu peux simplement écrire

const len = Math.ceil(Math.log10(num + 1));
MaxArt
la source
1
Je pense que cette mathématique pure est la plus efficace / la plus rapide.
Noitidart
2
Awesme perf man merci. Les résultats que j'ai obtenus montrent que la méthode mathématique est rapide, est-ce le résultat que vous avez obtenu? voici mon résultat: i.imgur.com/9BKxyd3.png
Noitidart
1
@HubertGrzeskowiak Oh c'est sympa. Je vois que cette méthode est fondamentalement mathématique de toute façon, mais avec quelques hacks de vitesse. Il laisse tomber un Math.ceilet utilise un plus rapide à la Math.absplace. Mais honnêtement, je ne m'attendais pas à ce gain de performances dans Chrome ... Bon à savoir!
MaxArt
3
Parfait, mais donne 0 si le nombre est 0 au lieu de 1
StateLess
1
À 1e + 16 ou plus, cela donne 1 de moins, donc 10000000000000000 renvoie 16 au lieu de 17 et ainsi de suite ...
Goty Metal
12

J'ai utilisé cette fonctionnalité dans node.js, c'est mon implémentation la plus rapide à ce jour:

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

Il doit gérer les entiers positifs et négatifs (également sous forme exponentielle) et doit renvoyer la longueur de la partie entière en flottants.

La référence suivante devrait fournir un aperçu de la méthode: Weisstein, Eric W. «Number Length». De MathWorld - Une ressource Web Wolfram.

Je crois qu'une opération au niveau du bit peut remplacer Math.abs, mais jsperf montre que Math.abs fonctionne très bien dans la majorité des moteurs js.

Mise à jour : comme indiqué dans les commentaires, cette solution présente quelques problèmes :(

Update2 (solution de contournement) : Je crois qu'à un moment donné, des problèmes de précision surviennent et que le Math.log(...)*0.434...se comporte de manière inattendue. Cependant, si Internet Explorer ou les appareils mobiles ne sont pas votre tasse de thé, vous pouvez remplacer cette opération par la Math.log10fonction. Dans Node.js, j'ai écrit un test de base rapide avec la fonction nLength = (n) => 1 + Math.log10(Math.abs(n) + 1) | 0;et avec Math.log10cela a fonctionné comme prévu. Veuillez noter que ce Math.log10n'est pas universellement pris en charge.

Israfil Havilah
la source
Par curiosité, j'ai effectué un JsPerf avec la méthode nLength vs toString (). Length sur ce .... jsperf.com/convert-number-to-string-and-get-length/2
Israfil Havilah
Haha, c'est fondamentalement la solution que j'ai fournie! Je n'avais aucune idée qu'il pouvait fonctionner aussi bien.
MaxArt
2
Je suis désolé, ai-je dit quelque chose sur moi en inventant la solution ou quelque chose comme ça? Pourquoi ne lisez-vous pas attentivement avant de publier? D'ailleurs, l'algorithme a été découvert bien avant la naissance de Steven Wolfram, et de toute façon la page que vous avez liée ne fournit pas de solution en Javascript. Je l'ai fait, 9 mois avant toi.
MaxArt
1
Le "+1" devrait probablement être en dehors de l'appel Math.abs: Math.log (Math.abs (n) + 1) ...
Hubert Grzeskowiak
1
À 1e + 16 ou plus, cela donne 1 de moins, donc 10000000000000000 renvoie 16 au lieu de 17 et ainsi de suite ...
Goty Metal
11

Vous devez faire le nombre en chaîne pour prendre de la longueur

var num = 123;

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

ou

alert(num.toString().length);
Adil
la source
9

Pourrait également utiliser une chaîne de modèle:

const num = 123456
`${num}`.length // 6
funador
la source
c'est la seule réponse qui fonctionne pour moi car je compte un nombre qui commence par 0.
jessiPP
5

Eh bien, sans convertir l'entier en chaîne, vous pouvez créer une boucle funky:

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

alert(length);​

Démo: http://jsfiddle.net/maniator/G8tQE/

Naftali alias Neal
la source
3
@Pointy oui, cela suppose un entier. Même si vous en faites une chaîne, elle inclura le .dans le cadre du calcul.
Naftali aka Neal
oui, bien que ce soit une question philosophique intéressante si le point doit être inclus dans la "longueur" :-)
Pointy
4

Commencez par le convertir en chaîne:

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

L'ajout d'une chaîne vide à celui-ci entraînera implicitement mynumbersa transformation en chaîne.

tskuzzy
la source
1
Ne fonctionne pas avec des exponentielles telles que 1e + 16 qui renvoie 5.
Goty Metal
4

Il y a trois façons de procéder.

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

meilleure performance (meilleure performance dans ie11)

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

Math (meilleures performances dans Chrome, Firefox mais plus lentes dans ie11)

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

il y a un jspref ici http://jsperf.com/fastest-way-to-get-the-first-in-a-number/2

Eric Chen
la source
4

Vous devriez opter pour le plus simple (stringLength), la lisibilité bat toujours la vitesse. Mais si vous vous souciez de la vitesse, voici quelques exemples ci-dessous.

Trois méthodes différentes, toutes à vitesse variable.

// 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
la source
3

On m'a posé une question similaire lors d'un test.

Trouver la longueur d'un nombre sans convertir en chaîne

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 ]

Des nombres négatifs ont été ajoutés pour le compliquer un peu plus, d'où Math.abs ().

Adrian Lynch
la source
2

Je voudrais corriger la réponse @Neal qui était assez bonne pour les entiers, mais le nombre 1 renverrait une longueur de 0 dans le cas précédent.

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
la source
0

Oui, vous devez convertir en chaîne pour trouver la longueur, par exemple

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
la source