JavaScript convierte un gran INT a notación científica cuando el número se vuelve grande. ¿Cómo puedo evitar que esto suceda?
translatetransformación que contenga coordenadas en notación científica.
JavaScript convierte un gran INT a notación científica cuando el número se vuelve grande. ¿Cómo puedo evitar que esto suceda?
translatetransformación que contenga coordenadas en notación científica.
Respuestas:
Hay Number.toFixed , pero usa notación científica si el número es> = 1e21 y tiene una precisión máxima de 20. Aparte de eso, puedes rodar el tuyo, pero será complicado.
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;
}
El anterior utiliza la repetición de cadenas cheap-'n'-easy ( (new Array(n+1)).join(str)). Puede definir el String.prototype.repeatuso de la multiplicación campesina rusa y utilizarlo en su lugar.
Esta respuesta solo debe aplicarse al contexto de la pregunta: mostrar un gran número sin usar notación científica. Para cualquier otra cosa, debe usar una biblioteca BigInt , como BigNumber , Leemon's BigInt o BigInteger . En el futuro, el nuevo BigInt nativo (nota: no Leemon's) debería estar disponible; Chromium y los navegadores basados en él ( Chrome , el nuevo Edge [v79 +], Brave ) y Firefox tienen soporte; El apoyo de Safari está en marcha.
Así es como usarías BigInt para ello: BigInt(n).toString()
Ejemplo:
Sin embargo, tenga en cuenta que cualquier número entero que ingrese como un número de JavaScript (no un BigInt) que tenga más de 15-16 dígitos (específicamente, mayor que Number.MAX_SAFE_INTEGER + 1[9,007,199,254,740,992]) puede redondearse, porque el tipo de número de JavaScript (IEEE-754 de doble precisión punto flotante) no puede contener con precisión todos los enteros más allá de ese punto. A partir de Number.MAX_SAFE_INTEGER + 1que funciona en múltiplos de 2, por lo que ya no puede contener números impares (y de manera similar, a 18,014,398,509,481,984 comienza a funcionar en múltiplos de 4, luego 8, luego 16, ...).
En consecuencia, si puede confiar en el BigIntsoporte, envíe su número como una cadena que pase a la BigIntfunción:
const n = BigInt("YourNumberHere");
Ejemplo:
Math.abs. Gracias por el aviso.
toFixed(Number.MAX_VALUE) == Number.MAX_VALUEdebe devolver cierto entonces, pero no es así ...
Sé que esta es una pregunta anterior, pero se muestra recientemente activa. 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"
puede usar opciones para formatear la salida.
Number.toLocaleString () se redondea después de 16 decimales, de modo que ...
const myNumb = 586084736227728377283728272309128120398;
console.log( myNumb.toLocaleString('fullwide', { useGrouping: false }) );
...devoluciones...
586084736227728400000000000000000000000
Esto quizás no sea deseable si la precisión es importante en el resultado deseado.
js console.log( myNumb.toLocaleString('fullwide', { useGrouping: true, maximumSignificantDigits:6}) );
Para un número pequeño, y sabe cuántos decimales desea, puede usar toFixed y luego usar una expresión regular para eliminar los ceros finales.
Number(1e-7).toFixed(8).replace(/\.?0+$/,"") //0.000
(1000).toFixed(0).replace(/\.?0+$/,"") // 1, not 1000
Una posible solución más:
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_INTEGERes probable que sufra este problema.
Aquí está mi pequeña variante de Number.prototype.toFixedmétodo que funciona con cualquier número:
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 lanza el primero a un Number, verá que son absolutamente iguales: jsfiddle.net/qd6hpnyx/1 . Puede retirar su :P
.0con una cadena vacía.
console.log(2.2e307.toFixedSpecial(10)). Quiero decir ... obtengo varios ceros al final. Votar de todos modos porque esto parece más cercano a lo que necesito.
La siguiente solución omite el formato exponencial automático para números muy grandes y muy pequeños. Esta es la solución de outis con una corrección de errores : no funcionaba para números negativos muy pequeños.
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));
¡Las respuestas de los demás no te dan el número exacto!
¡Esta función calcula el número deseado con precisión y lo devuelve en la cadena para evitar que JavaScript lo cambie!
Si necesita un resultado numérico, ¡simplemente multiplique el resultado de la función en el número uno!
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;
}
Uso .toPrecision, .toFixedetc. Puede contar el número de dígitos en su número al convertirlo en una cadena y .toStringluego mirarlo .length.
(2e64).toString()volverá "2e+64", por lo que .lengthes inútil.
Esto es lo que terminé usando para tomar el valor de una entrada, expandiendo números de menos de 17 dígitos y convirtiendo números exponenciales a 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;
}
}
Puede recorrer el número y lograr el redondeo
// funcionalidad para reemplazar char en un índice dado
String.prototype.replaceAt=function(index, character) {
return this.substr(0, index) + character + this.substr(index+character.length);
}
// comienza el bucle sobre el número
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--;
}
}
Traté de trabajar con la forma de cadena en lugar del número y esto pareció funcionar. Solo he probado esto en Chrome, pero debería ser universal:
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;
}
Creo que puede haber varias respuestas similares, pero aquí hay algo que se me ocurrió
// 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);
Nota: esto es tan preciso como las funciones matemáticas de JavaScript y tiene problemas al usar log en lugar de log10 en la línea anterior al ciclo for; escribirá 1000 en base-10 como 000, así que lo cambié a log10 porque la gente usará la base-10 de todos modos.
Puede que esta no sea una solución muy precisa, pero me enorgullece decir que puede traducir con éxito números a través de bases y que viene con una opción para comas.
Tu pregunta:
number :0x68656c6c6f206f72656f
display:4.9299704811152646e+23
Puede usar esto: https://github.com/MikeMcl/bignumber.js
Una biblioteca de JavaScript para aritmética decimal y no decimal de precisión arbitraria.
Me gusta esto:
let ten =new BigNumber('0x68656c6c6f206f72656f',16);
console.log(ten.toString(10));
display:492997048111526447310191
Sé que han pasado muchos años, pero recientemente había estado trabajando en un problema similar y quería publicar mi solución. La respuesta actualmente aceptada rellena la parte del exponente con 0, y la mía intenta encontrar la respuesta exacta, aunque en general no es perfectamente precisa para números muy grandes debido al límite de JS en la precisión de coma flotante.
Esto funciona para Math.pow(2, 100), devolviendo el valor correcto 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(/\..*/,""); }
con algunos problemas:
Destrozando las expresiones regulares. Esto no tiene problemas de precisión y no es mucho código.
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 solo lo está haciendo para mostrar, puede construir una matriz a partir de los dígitos antes de que se redondeen.
var num = Math.pow(2, 100);
var reconstruct = [];
while(num > 0) {
reconstruct.unshift(num % 10);
num = Math.floor(num / 10);
}
console.log(reconstruct.join(''));
Actualmente no existe una función nativa para disolver la notación científica. Sin embargo, para este propósito debe escribir su propia funcionalidad.
Aquí está mi:
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("");
}
Puede usar el módulo exponencial from . Es ligero y totalmente probado.
import fromExponential from 'from-exponential';
fromExponential(1.123e-10); // => '0.0000000001123'
También puede usar YourJS.fullNumber. Por ejemplo, YourJS.fullNumber(Number.MAX_VALUE)resulta en lo siguiente:
179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
También funciona para números realmente pequeños. YourJS.fullNumber(Number.MIN_VALUE)devuelve esto:
0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005
Es importante tener en cuenta que esta función siempre devolverá números finitos como cadenas pero devolverá números no finitos (por ejemplo, NaNo Infinity) como undefined.
Puede probarlo en la consola YourJS aquí .
Puedes usar number.toString(10.1):
console.log(Number.MAX_VALUE.toString(10.1));
Nota: actualmente funciona en Chrome, pero no en Firefox. La especificación dice que la raíz tiene que ser un número entero, por lo que esto resulta en un comportamiento poco confiable.
10.1 o 10o nada son equivalentes.
Tuve el mismo problema con la devolución de la notación científica de Oracle, pero necesitaba el número real para una url. Acabo de usar un truco PHP restando cero, y obtengo el número correcto.
por ejemplo 5.4987E7 es el val.
newval = val - 0;
newval ahora es igual a 54987000