Lösung für das Problem ungenauer JS-Zahlen

Lösung für das Problem ungenauer JS-Zahlen

Die verständlichste Erklärung des Genauigkeitsproblems

Beispielsweise ist die Zahl 1÷3=0,33333333... Jeder weiß, dass sich 3 unendlich oft wiederholt, und die Mathematik kann das ausdrücken, aber der Computer muss sie speichern, damit sie beim nächsten Mal abgerufen und verwendet werden kann. Aber 0,333333... diese Zahl wiederholt sich unendlich, wie lässt man den Computer sie speichern? Egal, wie groß der Speicher des Computers ist, er kann nicht alles speichern, richtig! Er kann also keinen Wert relativ zur Mathematik speichern, sondern nur einen ungefähren Wert. Wenn der Computer ihn also speichert und dann zur Verwendung herausnimmt, treten Genauigkeitsprobleme auf.

JS übertrifft die Präzision der Zahlenlösung

1. Die maximale sichere Zahl in js ist Math.pow(2,53) - 1. Wenn die Zahl diesen Wert überschreitet, geht die Genauigkeit verloren. Sie können das Problem lösen, indem Sie die Zahl wie folgt in eine Zeichenfolge umwandeln:

// js maximale sichere Zahl: Math.pow(2, 53)-1

sei a = '123456444565456.889'
sei b = '121231456.32'
// a + b = '123456565796913.209'

Funktion addTwo(a, b) {
    //1. Vergleiche die Längen zweier Zahlen und füge der kürzeren Zahl eine 0 voran
    if (a.Länge > b.Länge) {
        lass arr = Array(a.Länge - b.Länge).fill(0);
        b = arr.join('') + b
    } sonst wenn (a.Länge < b.Länge) {
        lass arr = Array(b.Länge - a.Länge).fill(0);
        a = arr.join('') + a
    }

    //2. Kehren Sie die beiden Zahlen um (das liegt daran, dass die Leute daran gewöhnt sind, von links nach rechts zu addieren, Zahlen jedoch von rechts nach links addiert werden, sodass die Umkehrung leichter zu verstehen ist)
    a = a.split('').reverse();
    b = b.split('').reverse();

    //3. Durchlaufe zwei Arrays und addiere sie. Wenn die Summe größer als 10 ist, dann ist das Vorzeichen = 1 und der Wert an der aktuellen Position ist (Summe % 10).
    let sign = 0; //markiere, ob ein Übertrag vorhanden ist let newVal = []; //wird verwendet, um das Endergebnis zu speichern for (let j = 0; j < a.length; j++) {
        let val = a[j] / 1 + b[j] / 1 + sign; // Durch 1 teilen, um sicherzustellen, dass alles Zahlen sind. Sie können hier auch Number() verwenden.
        wenn (Wert >= 10) {
            Zeichen = 1;
            newVal.unshift(val % 10) // unshift wird hier anstelle von push verwendet, da es die Verwendung von reverse erspart
        } anders {
            Vorzeichen = 0;
            newVal.unshift(Wert)
        }
    }

    // Die letzte Addition muss eine Ziffer '1' enthalten
    returniere Vorzeichen && newVal.unshift(Vorzeichen) && newVal.join('') || newVal.join('')
}

// Siehe die prägnante Schreibweise anderer Freunde function addTwo(a,b) {
    lass temp = 0
    lass res = ''
    a = a.split('')
    b = b.split('')
    während(a.Länge || b.Länge || temp) {
        temp += Zahl(a.pop() || 0) + Zahl(b.pop() || 0)
        res = (temp%10) + res
        temp = temp > 9
    }
    returniere res.replace(/^0+/g, '')
}

2. Wenn es um das Hinzufügen von Dezimalteilen geht, kapseln Sie die obige Methode einmal und die vollständige Implementierung lautet wie folgt:

sei a = '123456444565456.889'
sei b = '121231456.32'
// a + b = '123456565796913.209'

Funktion addTwo(a = '0',b = '0', isHasDecimal=false) {
    //1. Vergleiche die Längen zweier Zahlen und füge der kürzeren Zahl eine 0 voran
    if (a.Länge > b.Länge) {
        lass arr = Array(a.Länge - b.Länge).fill(0);
        b = isHasDecimal && (b + arr.join('')) || arr.join('') + b
    } sonst wenn (a.Länge < b.Länge) {
        lass arr = Array(b.Länge - a.Länge).fill(0);
        a = isHasDecimal && (a + arr.join('')) || arr.join('') + a
    }

    //2. Kehren Sie die beiden Zahlen um (das liegt daran, dass die Leute daran gewöhnt sind, von links nach rechts zu addieren, Zahlen jedoch von rechts nach links addiert werden, sodass die Umkehrung leichter zu verstehen ist)
    a = a.split('').reverse();
    b = b.split('').reverse();


    //3. Durchlaufe zwei Arrays und addiere sie. Wenn die Summe größer als 10 ist, dann ist das Vorzeichen = 1 und der Wert an der aktuellen Position ist (Summe % 10).
    let sign = 0; //markiere, ob ein Übertrag vorhanden ist let newVal = []; //wird verwendet, um das Endergebnis zu speichern for (let j = 0; j < a.length; j++) {
        let val = a[j] / 1 + b[j] / 1 + sign; // Durch 1 teilen, um sicherzustellen, dass alles Zahlen sind. Sie können hier auch Number() verwenden.
        wenn (Wert >= 10) {
            Zeichen = 1;
            newVal.unshift(val % 10) // unshift wird hier anstelle von push verwendet, da es die Verwendung von reverse erspart
        } anders {
            Vorzeichen = 0;
            newVal.unshift(Wert)
        }
    }

    // Die letzte Addition muss eine Ziffer '1' enthalten
    returniere Vorzeichen && newVal.unshift(Vorzeichen) && newVal.join('') || newVal.join('')
}

Funktion add(a,b) {
    lass num1 = String(a).split('.')
    lass num2 = String(b).split('.')
    let intSum = addTwo(num1[0], num2[0])
    lass res = intSum

    wenn (Anzahl1.Länge>1 || Anzahl2.Länge > 1) {
        let decimalSum = addTwo(num1[1], num2[1], true)

        wenn (Dezimalsumme.Länge > (Zahl1[1]||'0').Länge && Dezimalsumme.Länge > (Zahl2[1]||'0').Länge) {
            intSum = addTwo(intSum, decimalSum[0])
            decimalSum = decimalSum.slice(1)
            res = `${intSum}.${decimalSum}`
        } anders {
            res = `${intSum}.${decimalSum}`
        }
    }
    Rückgabewert
}
console.log(add(a, b)) // 123456565796913.209
// konsole.log(add('325', '988')) // 1313

Sehen Sie sich einige typische Probleme mit dem Verlust digitaler Präzision bei JS an

// Ergänzung =======================
0,1 + 0,2 = 0,30000000000000004
0,7 + 0,1 = 0,799999999999999
0,2 + 0,4 = 0,6000000000000001

// Subtraktion =======================
1,5 - 1,2 = 0,30000000000000004
0,3 - 0,2 = 0,099999999999999998

// Multiplikation =======================
19,9 * 100 = 1989,99999999999998
0,8 * 3 = 2,4000000000000004
35,41 * 100 = 3540,99999999999995

// Abteilung =======================
0,3 / 0,1 = 2,99999999999999996
0,69 / 10 = 0,0689999999999999

Zusammenfassen

Dies ist das Ende dieses Artikels zur Lösung des Problems ungenauer Zahlen in JS. Weitere relevante Inhalte zu ungenauen Zahlen in JS finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den verwandten Artikeln weiter unten. Ich hoffe, Sie werden 123WORDPRESS.COM auch in Zukunft unterstützen!

Das könnte Sie auch interessieren:
  • Detaillierte Erklärung zur Vermeidung digitaler Berechnungsgenauigkeitsfehler in Javascript
  • So lösen Sie das Problem des Verlusts numerischer Präzision in JavaScript
  • Analyse und Lösung der Ursache des digitalen Präzisionsverlusts von JS

<<:  Installieren von MySQL 8.0.12 basierend auf Windows

>>:  Erfahren Sie, wie Sie ein Vue-Projekt mit Docker bereitstellen

Artikel empfehlen

4 Möglichkeiten zum Anzeigen von Prozessen in LINUX (Zusammenfassung)

Ein Prozess ist ein Programmcode, der in der CPU ...

Tutorial zu HTML-Tabellen-Tags (3): Breiten- und Höhenattribute WIDTH, HEIGHT

Standardmäßig werden Breite und Höhe der Tabelle ...

Schritte zum Übertragen von Dateien und Ordnern zwischen zwei Linux-Servern

Heute habe ich mich mit der Migration eines Proje...

Neulinge lernen schnell die Schritte zum Erstellen von Website-Symbolen

<br />Original-URL: http://www.lxdong.com/po...

Prozessdiagramm zum Aufbau des Linux RabbitMQ-Clusters

1. Allgemeine Schritte Zu Beginn haben wir die In...

So implementieren Sie den Dienststatus zur Nginx-Konfigurationserkennung

1. Überprüfen Sie, ob das Modul „Status prüfen“ i...

Verwendung und Beispiele für Linux-Befehle zur Echotextverarbeitung

Die Beschreibung von echo im Linux-Hilfedokument ...

Detailliertes Tutorial zur Installation von mysql-8.0.20 unter Linux

** Installieren Sie mysql-8.0.20 unter Linux ** U...

Vergleich zwischen Redis und Memcache und Auswahlmöglichkeiten

Ich verwende Redis seit Kurzem und finde es recht...

Implementierung langer Textschatten in Less in CSS3

Dieser Artikel stellt hauptsächlich die Implement...

So schreiben Sie eleganten JS-Code

Inhaltsverzeichnis Variable Verwenden Sie aussage...

Implementierung eines Karussells mit nativem JavaScript

In diesem Artikel finden Sie den spezifischen Cod...

So verwenden Sie CSS-Zähler, um geordnete Zahlenlisten zu verschönern

Beim Webdesign ist es sehr wichtig, eine organisi...

Confluence mit Docker bereitstellen

1. Umweltanforderungen 1. Docker 17 und höher wur...

Häufig verwendete JavaScript-Array-Methoden

Inhaltsverzeichnis 1. filter() 2. fürJedes() 3. e...