314 Stimmen

Wie kann man die wissenschaftliche Notation für große Zahlen in JavaScript vermeiden?

JavaScript konvertiert ganze Zahlen mit mehr als 21 Ziffern in wissenschaftliche Notation, wenn sie in einem String-Kontext verwendet werden. Ich gebe eine ganze Zahl als Teil einer URL aus. Wie kann ich diese Umwandlung verhindern?

0voto

Sanford Staab Punkte 209

Ich habe versucht, mit der Zeichenkettenform statt mit der Zahl zu arbeiten, und das 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;
}

0voto

Martin Wantke Punkte 3753

Derzeit gibt es keine systemeigene Funktion zur Auflösung der wissenschaftlichen Notation. Für diesen Zweck müssen Sie jedoch eine eigene Funktion schreiben.

Hier ist meine:

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("");
}

0voto

andi Punkte 6372

Ich weiß, es ist schon viele Jahre her, aber ich habe mich kürzlich mit einem ähnlichen Problem beschäftigt und wollte meine Lösung veröffentlichen. Die derzeit akzeptierte Antwort füllt den Exponententeil mit 0en auf, und meine versucht, die exakte Antwort zu finden, obwohl sie im Allgemeinen für sehr große Zahlen wegen der Begrenzung der Fließkommagenauigkeit von JS nicht perfekt genau ist.

Dies funktioniert bei Math.pow(2, 100) und liefert den richtigen Wert von 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

0voto

lauri108 Punkte 1244

Wenn es Ihnen nichts ausmacht, mit Lodash hat sie toSafeInteger()

_.toSafeInteger(3.2);
// => 3

_.toSafeInteger(Number.MIN_VALUE);
// => 0

_.toSafeInteger(Infinity);
// => 9007199254740991

_.toSafeInteger('3.2');
// => 3

-1voto

Jake M Punkte 31

Wenn Sie es nur für die Anzeige tun, können Sie ein Array aus den Ziffern bilden, 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(''));

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X