2010-11-13 15 views
5

J'ai besoin d'obtenir la valeur d'un nombre extrêmement important dans JavaScript sous une forme non exponentielle. Number.toFixed le renvoie simplement sous forme exponentielle sous forme de chaîne, ce qui est pire que ce que j'avais.À l'opposé de Number.toExponential dans JS

C'est ce que Number.toFixed retours:

>>> x = 1e+31 
1e+31 
>>> x.toFixed() 
"1e+31" 

Number.toPrecision ne fonctionne pas non plus:

>>> x = 1e+31 
1e+31 
>>> x.toPrecision(21) 
"9.99999999999999963590e+30" 

Ce que je voudrais est:

>>> x = 1e+31 
1e+31 
>>> x.toNotExponential() 
"10000000000000000000000000000000" 

Je pourrais écrire mon propre analyseur mais Je préférerais utiliser une méthode JS native si elle existe.

Répondre

1

La réponse est qu'il n'y a pas une telle fonction intégrée. J'ai cherché haut et bas. Voici le RegExp que j'utilise pour diviser le nombre en signe, coefficient (chiffres avant le point décimal), partie décimale (chiffres après la virgule) et exposant:

/^([+-])?(\d+)\.?(\d*)[eE]([+-]?\d+)$/ 

« Réaliser votre propre » est la réponse, que vous déjà fait.

+0

J'ai depuis longtemps oublié ce que j'ai fait pour résoudre ce problème, mais vous avez raison de dire qu'il n'y a pas de méthode intégrée pour le faire. –

+0

@Oz Hey merci l'homme, enfin je peux commenter sur des questions! C'est une grande douleur avec les méthodes d'impression intégrées, quelque chose comme un "printf" serait sûrement bien. Je travaille actuellement sur une classe NumberFormatter personnalisée. –

4

Vous pouvez utiliser toPrecision avec un paramètre spécifiant le nombre de chiffres que vous souhaitez afficher:

x.toPrecision(31) 

Cependant, parmi les navigateurs que j'ai testé, le code ci-dessus ne fonctionne que sur Firefox. Selon la spécification ECMAScript, la plage valide pour toPrecision est comprise entre 1 et 21, et IE et Chrome lancent un RangeError en conséquence. Cela est dû au fait que la représentation à virgule flottante utilisée dans JavaScript est incapable de représenter réellement les nombres à 31 chiffres de précision.

+1

Je suis bien avec elle ne pas être un nombre réel quand je reçois (il est à des fins d'affichage), mais toPrecision doesn Ne travaillez pas pour des nombres supérieurs à 1e + 21. Dans ce cas particulier, je reçois "9.99999999999999963590e + 30". Je vais mettre à jour la question en conséquence. –

+0

@Oz: Oui, c'est ce que j'ai mentionné. Je ne pense pas qu'il existe un autre moyen intégré d'obtenir des chaînes pour un si grand nombre. – casablanca

0

Il est possible d'étendre la sortie exponentielle de JavaScript à l'aide de fonctions de chaîne. Il est vrai que ce que je suis venu quelque peu cryptique, mais il ne fonctionne que si l'exposant après la e est positif:

var originalNumber = 1e+31; 
var splitNumber = originalNumber.toString().split('e'); 

var result; 
if(splitNumber[1]) { 
    var regexMatch = splitNumber[0].match(/^([^.]+)\.?(.*)$/); 
    result = 
     /* integer part */ regexMatch[1] + 
     /* fractional part */ regexMatch[2] + 
     /* trailing zeros */ Array(splitNumber[1] - regexMatch[2].length + 1).join('0'); 
} else result = splitNumber[0]; 
+0

J'utilise actuellement ma propre fonction de conversion qui sépare la version toString du nombre, semblable à la vôtre, mais sans la jonction vide Array. Cependant, je suis à la recherche d'une fonction JS native pour le faire pour moi. –

1

« 10000000000000000000000000000000 »?

Difficile à croire que tout le monde serait plutôt regarder ce que 1.0E + 31,

ou en html: 10 . Mais voici une façon, une grande partie est pour les exposants négatifs (fractions):

function longnumberstring(n){ 
    var str, str2= '', data= n.toExponential().replace('.','').split(/e/i); 
    str= data[0], mag= Number(data[1]); 
    if(mag>=0 && str.length> mag){ 
     mag+=1; 
     return str.substring(0, mag)+'.'+str.substring(mag);    
    } 
    if(mag<0){ 
     while(++mag) str2+= '0'; 
     return '0.'+str2+str; 
    } 
    mag= (mag-str.length)+1; 
    while(mag> str2.length){ 
     str2+= '0'; 
    } 
    return str+str2; 
} 



input: 1e+30 
longnumberstring: 1000000000000000000000000000000 
to Number: 1e+30 
input: 1.456789123456e-30 
longnumberstring: 0.000000000000000000000000000001456789123456 
to Number: 1.456789123456e-30 
input: 1.456789123456e+30 
longnumberstring: 1456789123456000000000000000000 
to Number: 1.456789123456e+30 
input: 1e+80 longnumberstring: 100000000000000000000000000000000000000000000000000000000000000000000000000000000 
to Number: 1e+80 
+0

Il doit être affiché comme une valeur monétaire et $ 1e + 31 ne lisent pas bien. La valeur est si élevée parce que c'est l'entrée de l'utilisateur et les utilisateurs sont fous. Merci pour la fonction, mais j'ai déjà une fonction que j'ai écrite pour le faire, je me demandais s'il y en avait un intégré. –

1

numéro (string)

Exemple: var a=Number("1.1e+2"); donne a = 110

+0

C'est le contraire de ce que je vais faire. Il y a beaucoup de façons d'aller d'une chaîne à un nombre, mais je cherche à passer d'un très grand nombre à une chaîne sans utiliser l'exponentiation. –

+0

alors qu'est-ce à propos de var a = Number ("9.9E-8"); ?? Ça ne fonctionne pas.. :( –