JavaScript konvertiert eine große INT in eine wissenschaftliche Notation, wenn die Anzahl groß wird. Wie kann ich dies verhindern?
translateTransformation auftritt, die Koordinaten in wissenschaftlicher Notation enthält.
JavaScript konvertiert eine große INT in eine wissenschaftliche Notation, wenn die Anzahl groß wird. Wie kann ich dies verhindern?
translateTransformation auftritt, die Koordinaten in wissenschaftlicher Notation enthält.
Antworten:
Es gibt Number.toFixed , aber es verwendet die wissenschaftliche Notation, wenn die Zahl> = 1e21 ist und eine maximale Genauigkeit von 20 hat. Ansonsten können Sie Ihre eigene würfeln, aber es wird chaotisch.
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;
}
Oben wird eine billige und einfache Zeichenfolgenwiederholung verwendet ( (new Array(n+1)).join(str)). Sie können die String.prototype.repeatVerwendung der russischen Bauernmultiplikation definieren und diese stattdessen verwenden.
Diese Antwort sollte nur auf den Kontext der Frage angewendet werden: Anzeigen einer großen Anzahl ohne Verwendung der wissenschaftlichen Notation. Für alles andere sollten Sie eine BigInt- Bibliothek wie BigNumber , Leemons BigInt oder BigInteger verwenden . In Zukunft sollte das neue native BigInt (Hinweis: nicht Leemon's) verfügbar sein. Chromium und darauf basierende Browser ( Chrome , der neue Edge [v79 +], Brave ) und Firefox werden unterstützt. Die Unterstützung von Safari ist im Gange.
So würden Sie BigInt dafür verwenden: BigInt(n).toString()
Beispiel:
Hüten Sie sich vor , Sie jedoch, dass eine ganze Zahl Sie Ausgabe als JavaScript - Nummer (kein BigInt) , die mehr als 15 bis 16 Ziffern ist (genauer gesagt, größer ist als Number.MAX_SAFE_INTEGER + 1[9.007.199.254.740.992]) gerundet sein kann, weil JavaScript Nummer Typ (IEEE-754 mit doppelter Genauigkeit Gleitkomma) kann nicht alle ganzen Zahlen über diesen Punkt hinaus genau halten. Da Number.MAX_SAFE_INTEGER + 1es in Vielfachen von 2 arbeitet, kann es keine ungeraden Zahlen mehr halten (und ähnlich beginnt es bei 18.014.398.509.481.984 in Vielfachen von 4, dann 8, dann 16, ... zu arbeiten).
Wenn Sie sich auf BigIntUnterstützung verlassen können, geben Sie Ihre Nummer als Zeichenfolge aus, die Sie an die BigIntFunktion übergeben:
const n = BigInt("YourNumberHere");
Beispiel:
Math.abs. Danke für die Warnung.
toFixed(Number.MAX_VALUE) == Number.MAX_VALUEsollte dann wahr zurückgeben, aber es tut nicht ...
Ich weiß, dass dies eine ältere Frage ist, zeigt aber vor kurzem aktiv. 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"
Sie können Optionen verwenden, um die Ausgabe zu formatieren.
Number.toLocaleString () rundet nach 16 Dezimalstellen, so dass ...
const myNumb = 586084736227728377283728272309128120398;
console.log( myNumb.toLocaleString('fullwide', { useGrouping: false }) );
...kehrt zurück...
586084736227728400000000000000000000000
Dies ist möglicherweise unerwünscht, wenn die Genauigkeit für das beabsichtigte Ergebnis wichtig ist.
js console.log( myNumb.toLocaleString('fullwide', { useGrouping: true, maximumSignificantDigits:6}) );
Für kleine Zahlen und wenn Sie wissen, wie viele Dezimalstellen Sie möchten, können Sie toFixed verwenden und dann einen regulären Ausdruck verwenden, um die nachfolgenden Nullen zu entfernen.
Number(1e-7).toFixed(8).replace(/\.?0+$/,"") //0.000
(1000).toFixed(0).replace(/\.?0+$/,"") // 1, not 1000
eine weitere mögliche Lösung:
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_INTEGERwahrscheinlich, leidet unter diesem Problem.
Hier ist meine kurze Variante der Number.prototype.toFixedMethode, die mit einer beliebigen Zahl funktioniert:
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. Wenn Sie den ersten in a umwandelnNumber , werden Sie feststellen, dass sie absolut gleich sind: jsfiddle.net/qd6hpnyx/1 . Sie können Ihre Gegenstimme zurücknehmen:P
.0durch leere Zeichenfolgen zu ersetzen .
console.log(2.2e307.toFixedSpecial(10)). Ich meine ... ich bekomme mehrere nachgestellte Nullen. Upvoting sowieso, weil dies dem am nächsten kommt, was ich brauche.
Die folgende Lösung umgeht die automatische exponentielle Formatierung für sehr große und sehr kleine Zahlen. Dies ist die Lösung von outis mit einem Bugfix: Es funktionierte nicht für sehr kleine negative Zahlen.
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));
Die Antworten anderer geben Ihnen nicht die genaue Zahl!
Diese Funktion berechnet die gewünschte Zahl genau und gibt sie in der Zeichenfolge zurück, um zu verhindern, dass sie durch Javascript geändert wird!
Wenn Sie ein numerisches Ergebnis benötigen, multiplizieren Sie einfach das Ergebnis der Funktion mit Nummer eins!
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;
}
Verwendung .toPrecision, .toFixedusw. Sie können die Anzahl der Stellen in der Zahl zählen , indem es in einen String mit der Umwandlung .toStringdann zugleich in ihrem .length.
(2e64).toString()wird zurückkehren "2e+64", .lengthist also nutzlos.
Dies ist, was ich letztendlich verwendet habe, um den Wert von einer Eingabe zu übernehmen, Zahlen mit weniger als 17 Ziffern zu erweitern und Exponentialzahlen in x10 y umzuwandeln
// 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;
}
}
Sie können die Zahl durchlaufen und die Rundung erreichen
// Funktionalität zum Ersetzen von char am angegebenen Index
String.prototype.replaceAt=function(index, character) {
return this.substr(0, index) + character + this.substr(index+character.length);
}
// Schleife über die Nummer beginnt
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--;
}
}
Ich habe versucht, mit der Zeichenfolgeform und nicht mit der Zahl zu arbeiten, und dies schien zu funktionieren. Ich habe dies nur auf Chrome getestet, aber es sollte universell sein:
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;
}
Ich denke, es gibt vielleicht mehrere ähnliche Antworten, aber hier ist eine Sache, die ich mir ausgedacht habe
// 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);
Hinweis: Dies ist nur so genau wie die JavaScript-Mathematikfunktionen und hat Probleme bei der Verwendung von log anstelle von log10 in der Zeile vor der for-Schleife. Es wird 1000 in Base-10 als 000 schreiben, also habe ich es in log10 geändert, weil die Leute sowieso sowieso meistens Base-10 verwenden.
Dies ist möglicherweise keine sehr genaue Lösung, aber ich bin stolz darauf, dass sie Zahlen erfolgreich über Basen hinweg übersetzen kann und eine Option für Kommas enthält!
Ihre Frage:
number :0x68656c6c6f206f72656f
display:4.9299704811152646e+23
Sie können dies verwenden: https://github.com/MikeMcl/bignumber.js
Eine JavaScript-Bibliothek für Dezimal- und Nicht-Dezimal-Arithmetik mit beliebiger Genauigkeit.
so was:
let ten =new BigNumber('0x68656c6c6f206f72656f',16);
console.log(ten.toString(10));
display:492997048111526447310191
Ich weiß, dass es viele Jahre später ist, aber ich hatte kürzlich an einem ähnlichen Problem gearbeitet und wollte meine Lösung veröffentlichen. Die aktuell akzeptierte Antwort füllt den Exponententeil mit Nullen auf, und meine versucht, die genaue Antwort zu finden, obwohl sie im Allgemeinen für sehr große Zahlen aufgrund der JS-Grenze für die Gleitkommapräzision nicht perfekt genau ist.
Dies funktioniert für Math.pow(2, 100)und gibt den korrekten Wert von 1267650600228229401496703205376 zurück.
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(/\..*/,""); }
mit einigen Problemen:
Die regulären Ausdrücke ausschalten. Dies hat keine Präzisionsprobleme und ist nicht viel 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));
Wenn Sie dies nur zur Anzeige tun, können Sie aus den Ziffern ein Array erstellen, bevor sie gerundet werden.
var num = Math.pow(2, 100);
var reconstruct = [];
while(num > 0) {
reconstruct.unshift(num % 10);
num = Math.floor(num / 10);
}
console.log(reconstruct.join(''));
Derzeit gibt es keine native Funktion zum Auflösen der wissenschaftlichen Notation. Zu diesem Zweck müssen Sie jedoch Ihre eigenen Funktionen schreiben.
Hier ist mein:
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("");
}
Sie können ein Exponentialmodul verwenden . Es ist leicht und vollständig getestet.
import fromExponential from 'from-exponential';
fromExponential(1.123e-10); // => '0.0000000001123'
Sie können auch YourJS.fullNumber verwenden. Zum Beispiel YourJS.fullNumber(Number.MAX_VALUE)ergibt sich Folgendes:
179769313486231570000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
Es funktioniert auch für sehr kleine Zahlen. YourJS.fullNumber(Number.MIN_VALUE)gibt dies zurück:
0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005
Es ist wichtig zu beachten, dass diese Funktion immer endliche Zahlen als Zeichenfolgen zurückgibt, aber nicht endliche Zahlen (z. B. NaNoder Infinity) als undefined.
Sie können es hier in der YourJS-Konsole testen .
Sie können verwenden number.toString(10.1):
console.log(Number.MAX_VALUE.toString(10.1));
Hinweis: Dies funktioniert derzeit in Chrome, jedoch nicht in Firefox. Die Spezifikation besagt, dass der Radix eine ganze Zahl sein muss, was zu einem unzuverlässigen Verhalten führt.
10.1 oder 10oder nichts sind also gleichwertig.
Ich hatte das gleiche Problem mit Orakel, das die wissenschaftliche Notation zurückgibt, aber ich brauchte die tatsächliche Nummer für eine URL. Ich habe gerade einen PHP-Trick verwendet, indem ich Null subtrahiert habe, und ich bekomme die richtige Zahl.
Zum Beispiel ist 5.4987E7 der Wert.
newval = val - 0;
newval ist jetzt gleich 54987000