JavaScript convertit un grand INT en notation scientifique lorsque le nombre devient grand. Comment éviter que cela ne se produise?
translatetransformation qui contient des coordonnées en notation scientifique.
JavaScript convertit un grand INT en notation scientifique lorsque le nombre devient grand. Comment éviter que cela ne se produise?
translatetransformation qui contient des coordonnées en notation scientifique.
Réponses:
Il y a Number.toFixed , mais il utilise la notation scientifique si le nombre est> = 1e21 et a une précision maximale de 20. À part cela, vous pouvez lancer le vôtre, mais ce sera compliqué.
function toFixed(x) {
if (Math.abs(x) < 1.0) {
var e = parseInt(x.toString().split('e-')[1]);
if (e) {
x *= Math.pow(10,e-1);
x = '0.' + (new Array(e)).join('0') + x.toString().substring(2);
}
} else {
var e = parseInt(x.toString().split('+')[1]);
if (e > 20) {
e -= 20;
x /= Math.pow(10,e);
x += (new Array(e+1)).join('0');
}
}
return x;
}
Ci-dessus utilise la répétition de chaîne bon marché et facile ( (new Array(n+1)).join(str)). Vous pouvez définir l' String.prototype.repeatutilisation de la multiplication paysanne russe et l'utiliser à la place.
Cette réponse ne doit être appliquée qu'au contexte de la question: afficher un grand nombre sans utiliser de notation scientifique. Pour toute autre chose, vous devez utiliser une bibliothèque BigInt , telle que BigNumber , Leemon's BigInt ou BigInteger . À l'avenir, le nouveau BigInt natif (note: pas celui de Leemon) devrait être disponible; Chrome et les navigateurs basés sur celui-ci ( Chrome , le nouveau Edge [v79 +], Brave ) et Firefox ont tous un support; Le support de Safari est en cours.
Voici comment vous utiliseriez BigInt pour cela: BigInt(n).toString()
Exemple:
Attention , cependant, que tout entier vous sortie en tant que numéro JavaScript (pas BigInt) qui est plus de 15-16 chiffres ( en particulier, supérieur à Number.MAX_SAFE_INTEGER + 1[9.007.199.254.740.992]) peut être être arrondi, car le type de numéro JavaScript (double précision IEEE-754 virgule flottante) ne peut pas contenir précisément tous les nombres entiers au-delà de ce point. À partir du moment où Number.MAX_SAFE_INTEGER + 1il fonctionne par multiples de 2, il ne peut donc plus contenir de nombres impairs (et de manière similaire, à 18 014 398 509 481 984, il commence à fonctionner par multiples de 4, puis 8, puis 16, ...).
Par conséquent, si vous pouvez compter sur le BigIntsupport, affichez votre numéro sous forme de chaîne que vous passez à la BigIntfonction:
const n = BigInt("YourNumberHere");
Exemple:
Math.abs. Merci pour l'information.
toFixed(Number.MAX_VALUE) == Number.MAX_VALUEdevrait retourner vrai alors, mais ce n'est pas le cas ...
Je sais que c'est une question plus ancienne, mais montre récemment active. MDN toLocaleString
const myNumb = 1000000000000000000000;
console.log( myNumb ); // 1e+21
console.log( myNumb.toLocaleString() ); // "1,000,000,000,000,000,000,000"
console.log( myNumb.toLocaleString('fullwide', {useGrouping:false}) ); // "1000000000000000000000"
vous pouvez utiliser des options pour formater la sortie.
Number.toLocaleString () arrondit après 16 décimales, de sorte que ...
const myNumb = 586084736227728377283728272309128120398;
console.log( myNumb.toLocaleString('fullwide', { useGrouping: false }) );
...Retour...
586084736227728400000000000000000000000
Ceci n'est peut-être pas souhaitable si la précision est importante dans le résultat attendu.
js console.log( myNumb.toLocaleString('fullwide', { useGrouping: true, maximumSignificantDigits:6}) );
Pour un petit nombre, et vous savez combien de décimales vous voulez, vous pouvez utiliser toFixed puis utiliser une expression régulière pour supprimer les zéros de fin.
Number(1e-7).toFixed(8).replace(/\.?0+$/,"") //0.000
(1000).toFixed(0).replace(/\.?0+$/,"") // 1, not 1000
une autre solution possible:
function toFix(i){
var str='';
do{
let a = i%10;
i=Math.trunc(i/10);
str = a+str;
}while(i>0)
return str;
}
Number.MAX_SAFE_INTEGERest susceptible de souffrir de ce problème.
Voici ma courte variante de Number.prototype.toFixedméthode qui fonctionne avec n'importe quel nombre:
Number.prototype.toFixedSpecial = function(n) {
var str = this.toFixed(n);
if (str.indexOf('e+') === -1)
return str;
// if number is in scientific notation, pick (b)ase and (p)ower
str = str.replace('.', '').split('e+').reduce(function(p, b) {
return p + Array(b - p.length + 2).join(0);
});
if (n > 0)
str += '.' + Array(n + 1).join(0);
return str;
};
console.log( 1e21.toFixedSpecial(2) ); // "1000000000000000000000.00"
console.log( 2.1e24.toFixedSpecial(0) ); // "2100000000000000000000000"
console.log( 1234567..toFixedSpecial(1) ); // "1234567.0"
console.log( 1234567.89.toFixedSpecial(3) ); // "1234567.890"
Number. Si vous lancez le premier en a Number, vous verrez qu'ils sont absolument égaux: jsfiddle.net/qd6hpnyx/1 . Vous pouvez retirer votre :P
.0par une chaîne vide.
console.log(2.2e307.toFixedSpecial(10)). Je veux dire ... j'obtiens plusieurs zéros à la fin. De toute façon, voter pour parce que cela me semble le plus proche de ce dont j'ai besoin.
La solution suivante contourne le formatage exponentiel automatique pour les très grands et très petits nombres. C'est la solution d' Outis avec un bug: cela ne fonctionnait pas pour de très petits nombres négatifs.
function numberToString(num)
{
let numStr = String(num);
if (Math.abs(num) < 1.0)
{
let e = parseInt(num.toString().split('e-')[1]);
if (e)
{
let negative = num < 0;
if (negative) num *= -1
num *= Math.pow(10, e - 1);
numStr = '0.' + (new Array(e)).join('0') + num.toString().substring(2);
if (negative) numStr = "-" + numStr;
}
}
else
{
let e = parseInt(num.toString().split('+')[1]);
if (e > 20)
{
e -= 20;
num /= Math.pow(10, e);
numStr = num.toString() + (new Array(e + 1)).join('0');
}
}
return numStr;
}
// testing ...
console.log(numberToString(+0.0000000000000000001));
console.log(numberToString(-0.0000000000000000001));
console.log(numberToString(+314564649798762418795));
console.log(numberToString(-314564649798762418795));
Les réponses des autres ne vous donnent pas le nombre exact!
Cette fonction calcule le nombre souhaité avec précision et le renvoie dans la chaîne pour éviter qu'il ne soit modifié par javascript!
Si vous avez besoin d'un résultat numérique, multipliez simplement le résultat de la fonction par le numéro un!
function toNonExponential(value) {
// if value is not a number try to convert it to number
if (typeof value !== "number") {
value = parseFloat(value);
// after convert, if value is not a number return empty string
if (isNaN(value)) {
return "";
}
}
var sign;
var e;
// if value is negative, save "-" in sign variable and calculate the absolute value
if (value < 0) {
sign = "-";
value = Math.abs(value);
}
else {
sign = "";
}
// if value is between 0 and 1
if (value < 1.0) {
// get e value
e = parseInt(value.toString().split('e-')[1]);
// if value is exponential convert it to non exponential
if (e) {
value *= Math.pow(10, e - 1);
value = '0.' + (new Array(e)).join('0') + value.toString().substring(2);
}
}
else {
// get e value
e = parseInt(value.toString().split('e+')[1]);
// if value is exponential convert it to non exponential
if (e) {
value /= Math.pow(10, e);
value += (new Array(e + 1)).join('0');
}
}
// if value has negative sign, add to it
return sign + value;
}
Utilisation .toPrecision, .toFixedetc. Vous pouvez compter le nombre de chiffres dans votre numéro en le convertissant en une chaîne avec la .toStringrecherche puis à son .length.
(2e64).toString()reviendra "2e+64", donc .lengthest inutile.
C'est ce que j'ai fini par utiliser pour prendre la valeur d'une entrée, en développant les nombres de moins de 17 chiffres et en convertissant les nombres exponentiels en x10 y
// e.g.
// niceNumber("1.24e+4") becomes
// 1.24x10 to the power of 4 [displayed in Superscript]
function niceNumber(num) {
try{
var sOut = num.toString();
if ( sOut.length >=17 || sOut.indexOf("e") > 0){
sOut=parseFloat(num).toPrecision(5)+"";
sOut = sOut.replace("e","x10<sup>")+"</sup>";
}
return sOut;
}
catch ( e) {
return num;
}
}
Vous pouvez boucler le nombre et réaliser l'arrondi
// fonctionnalité pour remplacer char à un index donné
String.prototype.replaceAt=function(index, character) {
return this.substr(0, index) + character + this.substr(index+character.length);
}
// boucle sur le nombre commence
var str = "123456789123456799.55";
var arr = str.split('.');
str = arr[0];
i = (str.length-1);
if(arr[1].length && Math.round(arr[1]/100)){
while(i>0){
var intVal = parseInt(str.charAt(i));
if(intVal == 9){
str = str.replaceAt(i,'0');
console.log(1,str)
}else{
str = str.replaceAt(i,(intVal+1).toString());
console.log(2,i,(intVal+1).toString(),str)
break;
}
i--;
}
}
J'ai essayé de travailler avec la forme de chaîne plutôt que le nombre et cela semblait fonctionner. Je n'ai testé cela que sur Chrome mais cela devrait être universel:
function removeExponent(s) {
var ie = s.indexOf('e');
if (ie != -1) {
if (s.charAt(ie + 1) == '-') {
// negative exponent, prepend with .0s
var n = s.substr(ie + 2).match(/[0-9]+/);
s = s.substr(2, ie - 2); // remove the leading '0.' and exponent chars
for (var i = 0; i < n; i++) {
s = '0' + s;
}
s = '.' + s;
} else {
// positive exponent, postpend with 0s
var n = s.substr(ie + 1).match(/[0-9]+/);
s = s.substr(0, ie); // strip off exponent chars
for (var i = 0; i < n; i++) {
s += '0';
}
}
}
return s;
}
Je pense qu'il peut y avoir plusieurs réponses similaires, mais voici une chose que j'ai trouvée
// If you're gonna tell me not to use 'with' I understand, just,
// it has no other purpose, ;( andthe code actually looks neater
// 'with' it but I will edit the answer if anyone insists
var commas = false;
function digit(number1, index1, base1) {
with (Math) {
return floor(number1/pow(base1, index1))%base1;
}
}
function digits(number1, base1) {
with (Math) {
o = "";
l = floor(log10(number1)/log10(base1));
for (var index1 = 0; index1 < l+1; index1++) {
o = digit(number1, index1, base1) + o;
if (commas && i%3==2 && i<l) {
o = "," + o;
}
}
return o;
}
}
// Test - this is the limit of accurate digits I think
console.log(1234567890123450);
Remarque: cela n'est aussi précis que les fonctions mathématiques javascript et pose des problèmes lors de l'utilisation de log au lieu de log10 sur la ligne avant la boucle for; il écrira 1000 en base-10 comme 000 donc je l'ai changé en log10 parce que les gens utiliseront principalement la base-10 de toute façon.
Ce n'est peut-être pas une solution très précise, mais je suis fier de dire qu'elle peut traduire avec succès des nombres d'une base à l'autre et est livrée avec une option pour les virgules!
Ta question:
number :0x68656c6c6f206f72656f
display:4.9299704811152646e+23
Vous pouvez utiliser ceci: https://github.com/MikeMcl/bignumber.js
Une bibliothèque JavaScript pour l'arithmétique décimale et non décimale de précision arbitraire.
comme ça:
let ten =new BigNumber('0x68656c6c6f206f72656f',16);
console.log(ten.toString(10));
display:492997048111526447310191
Je sais que c'est plusieurs années plus tard, mais j'avais récemment travaillé sur un problème similaire et je voulais publier ma solution. La réponse actuellement acceptée remplit la partie exposant avec des 0, et la mienne tente de trouver la réponse exacte, bien qu'en général elle ne soit pas parfaitement précise pour les très grands nombres en raison de la limite de JS en précision en virgule flottante.
Cela fonctionne pour Math.pow(2, 100), renvoyant la valeur correcte de 1267650600228229401496703205376.
function toFixed(x) {
var result = '';
var xStr = x.toString(10);
var digitCount = xStr.indexOf('e') === -1 ? xStr.length : (parseInt(xStr.substr(xStr.indexOf('e') + 1)) + 1);
for (var i = 1; i <= digitCount; i++) {
var mod = (x % Math.pow(10, i)).toString(10);
var exponent = (mod.indexOf('e') === -1) ? 0 : parseInt(mod.substr(mod.indexOf('e')+1));
if ((exponent === 0 && mod.length !== i) || (exponent > 0 && exponent !== i-1)) {
result = '0' + result;
}
else {
result = mod.charAt(0) + result;
}
}
return result;
}
console.log(toFixed(Math.pow(2,100))); // 1267650600228229401496703205376
toFixed(Number.MAX_VALUE) == Number.MAX_VALUE
function printInt(n) { return n.toPrecision(100).replace(/\..*/,""); }
avec quelques problèmes:
Briser les expressions régulières. Cela n'a pas de problèmes de précision et ce n'est pas beaucoup de code.
function toPlainString(num) {
return (''+num).replace(/(-?)(\d*)\.?(\d+)e([+-]\d+)/,
function(a,b,c,d,e) {
return e < 0
? b + '0.' + Array(1-e-c.length).join(0) + c + d
: b + c + d + Array(e-d.length+1).join(0);
});
}
console.log(toPlainString(12345e+12));
console.log(toPlainString(12345e+24));
console.log(toPlainString(-12345e+24));
console.log(toPlainString(12345e-12));
console.log(toPlainString(123e-12));
console.log(toPlainString(-123e-12));
console.log(toPlainString(-123.45e-56));
Si vous le faites uniquement pour l'affichage, vous pouvez créer un tableau à partir des chiffres avant qu'ils ne soient arrondis.
var num = Math.pow(2, 100);
var reconstruct = [];
while(num > 0) {
reconstruct.unshift(num % 10);
num = Math.floor(num / 10);
}
console.log(reconstruct.join(''));
Actuellement, il n'y a pas de fonction native pour dissoudre la notation scientifique. Cependant, pour cela, vous devez écrire votre propre fonctionnalité.
Voici mon:
function dissolveExponentialNotation(number)
{
if(!Number.isFinite(number)) { return undefined; }
let text = number.toString();
let items = text.split('e');
if(items.length == 1) { return text; }
let significandText = items[0];
let exponent = parseInt(items[1]);
let characters = Array.from(significandText);
let minus = characters[0] == '-';
if(minus) { characters.splice(0, 1); }
let indexDot = characters.reduce((accumulator, character, index) =>
{
if(!accumulator.found) { if(character == '.') { accumulator.found = true; } else { accumulator.index++; } }
return accumulator;
}, { index: 0, found: false }).index;
characters.splice(indexDot, 1);
indexDot += exponent;
if(indexDot >= 0 && indexDot < characters.length - 1)
{
characters.splice(indexDot, 0, '.');
}
else if(indexDot < 0)
{
characters.unshift("0.", "0".repeat(-indexDot));
}
else
{
characters.push("0".repeat(indexDot - characters.length));
}
return (minus ? "-" : "") + characters.join("");
}
Vous pouvez utiliser le module exponentiel . Il est léger et entièrement testé.
import fromExponential from 'from-exponential';
fromExponential(1.123e-10); // => '0.0000000001123'
Vous pouvez également utiliser YourJS.fullNumber. Par exemple, cela YourJS.fullNumber(Number.MAX_VALUE)donne les résultats suivants:
179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Cela fonctionne également pour de très petits nombres. YourJS.fullNumber(Number.MIN_VALUE)renvoie ceci:
0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005
Il est important de noter que cette fonction retournera toujours des nombres finis sous forme de chaînes mais renverra des nombres non finis (par exemple NaNou Infinity) sous forme de undefined.
Vous pouvez le tester dans la console YourJS ici .
Vous pouvez utiliser number.toString(10.1):
console.log(Number.MAX_VALUE.toString(10.1));
Remarque: cela fonctionne actuellement dans Chrome, mais pas dans Firefox. La spécification indique que la base doit être un entier, ce qui entraîne un comportement peu fiable.
10.1 ou 10ou rien est équivalent.
J'ai eu le même problème avec oracle retournant la notation scientifique, mais j'avais besoin du numéro réel pour une URL. Je viens d'utiliser une astuce PHP en soustrayant zéro, et j'obtiens le bon nombre.
par exemple 5.4987E7 est le val.
newval = val - 0;
newval vaut maintenant 54987000