Detaillierte Diskussion über Speicher und Variablenspeicher in JS

Detaillierte Diskussion über Speicher und Variablenspeicher in JS

Vorwort

Da im Front-End-Bereich die meiste Arbeit mit der Benutzeroberfläche erledigt wird, ist die Speicherverwaltung der am leichtesten zu übersehende Teil. Wenn Sie sich mit dem Speicher nicht auskennen, können Sie die Essenz vieler Probleme nicht erkennen und es fällt Ihnen schwer, qualifizierteren Code zu schreiben. Dieses Mal werde ich Sie in die Welt des Speichers entführen.

JS Magische Zahl

Fall 1: Berechnung und Überweisung des Betrages

18,9 * 100
=1889,99999999999998

Fall 2: Verletzung mathematischer Gesetze

0,1 + 0,2 === 0,3
// FALSCH

(Funktion (a, b, c) {
    gibt a + b + c === a + ( b + c ) zurück
})(0,1, 0,2, 0,3)
// FALSCH

Fall 3: Endlosschleifenaddition

(Funktion (Num) {
    während(wahr) {
        wenn (++num % 13 === 0) {
            Rückgabenummer
        }
    }
})(2 ** 53)

Fall 4: JSON.parse

JSON.parse('{"a":180143985094813214124}')
//{a: 180143985094813220000}

Aus den obigen vier Fällen können wir ersehen, dass Zahlenberechnungen in Computern oft einige „Überraschungen“ mit sich bringen. Um diese unerwarteten Ergebnisse zu vermeiden, müssen wir zunächst verstehen, wie Zahlen in Javascript gespeichert werden.

Nummern speichern

Computer speichern Daten im Binärsystem, daher müssen Zahlen auch in das entsprechende Binärsystem umgewandelt werden: verschiedene Kombinationen von 000 oder 111.

So konvertieren Sie Binärzahlen

Wie man eine Zahl in eine Binärzahl umwandelt, verdeutlicht ein Beispiel:

Wandeln Sie die Dezimalzahl 106.6953125106.6953125106.6953125 in eine Binärzahl um

Bei einer Dezimalumwandlung müssen Sie die Ganzzahl- und Dezimalteile separat verarbeiten. Teilen Sie die Ganzzahl 106106106 durch 222, bis der Quotient 000 beträgt, und nehmen Sie das Restergebnis jeder Division durch 222.

106 / 2 = 53 ... 0
53 / 2 = 26 ... 1
26 / 2 = 13 ... 0
13 / 2 = 6 ... 1
6 / 2 = 3 ... 0
3 / 2 = 1 ... 1
1 / 2 = 0 ... 1
Das Ergebnis ist der Rest von rechts nach links 1101010

Multiplizieren Sie die Dezimalzahl 0,69531250,69531250,6953125 mit 222, bis keine Dezimalstellen mehr vorhanden sind, und zählen Sie die ganzzahligen Ergebnisse nach jeder Multiplikation.

0,6953125 x 2 = 1,390625 ... 1
0,390625 x 2 = 0,78125 ... 0
0,78125 x 2 = 1,5625 ... 1
0,5625 x 2 = 1,125 ... 1
0,125 x 2 = 0,25 ... 0
0,25 x 2 = 0,5 ... 0
0,5 x 2 = 1 ... 1
Das Ergebnis sind die von links nach rechts angeordneten Ganzzahlen 1011001

Wenn man die berechnete 000 111-Folge zusammensetzt, erhält man die konvertierte Binärzahl 1101010.10110011101010.10110011101010.1011001, die in wissenschaftlicher Notation als 1.1010101011001∗261.1010101011001*2^61.1010101011001∗26 ausgedrückt wird. Nachdem die Binärzahl berechnet wurde, muss sie im Computer gespeichert werden. In Javascript wird zwischen Ganzzahlen und Dezimalzahlen nicht unterschieden, und Zahlen werden einheitlich gemäß den Anforderungen für Gleitkommazahlen mit doppelter Genauigkeit gespeichert, die hauptsächlich die folgenden Regeln umfassen:

  • Verwenden Sie 8 Bytes (64 Bits) 8 Bytes (64 Bits) 8 Bytes (64 Bits), um Gleitkommazahlen mit doppelter Genauigkeit zu speichern
  • Speichert durch Dezimalzahlen dargestellte Daten in wissenschaftlicher Notation
  • Das erste Bit gibt das Vorzeichen an, und die letzten 111111 Bits geben den Exponenten an. Der Exponent wird durch die Bitfülloperation berechnet, d. h., 102310231023 wird direkt zum Exponentenbit addiert.
  • Die restlichen 525252 Ziffern stellen das Dezimalkomma dar. Der über 525252 Ziffern hinausgehende Teil wird auf 000 abgerundet und auf 111 aufgerundet.

Da die 11 Bits des Exponenten nicht das Vorzeichenbit enthalten, wird ein Exponenten-Offset eingeführt, um den Effekt positiver und negativer Exponenten zu erzielen.

Das Diagramm sieht wie folgt aus:

Wir legen die konvertierten Binärzahlen gemäß den Regeln in den Speicher. Erstens ist 106.6953125106.6953125106.6953125 eine positive Zahl, daher sollte das Vorzeichenbit 111 sein. 000 steht für ein positives Vorzeichen und 111 für ein negatives Vorzeichen (auf dem Bild sollte 000 stehen, das ist ein Tippfehler)

Binär 1.1010101011001∗261.1010101011001*2^61.1010101011001∗26 Der Exponent ist 666 (hier muss noch der Offset 1023 addiert werden), was ins Binärsystem als 100000001011000000010110000000101 umgewandelt wird. Im Exponentenbit muss das Zweierkomplement stehen, und die Berechnungsregel für das Zweierkomplement lautet:

  • Das Komplement einer positiven Zahl ist sie selbst
  • Das Komplement einer negativen Zahl basiert auf ihrem ursprünglichen Code, wobei das Vorzeichenbit unverändert bleibt, die restlichen Bits invertiert werden und schließlich +1 ist. (Das heißt, +1 auf der Grundlage des Einerkomplements)
[+1] = [00000001] Original = [00000001] Umgekehrt [-1] = [10000001] Original = [11111110] Umgekehrt

Der Bildindex sollte also gefüllt sein

Der Mantissenteil kann direkt mit der aus der Dezimalzahl umgewandelten Binärzahl ausgefüllt werden.

In dieser Form werden die Zahlen schließlich im Computer gespeichert

warum 0,1 + 0,2 !== 0,3?

Nachdem wir das Prinzip der digitalen Speicherung verstanden haben, analysieren wir, warum 0,1+0,2!==0,30,1 + 0,2 !== 0,30,1+0,2!==0,3

Konvertieren Sie zunächst 0.10.10.1 0.20.20.2 0.30.30.3 in Binärzahlen.

0,1 x 2 = 0,2 ... 0
0,2 x 2 = 0,4 ... 0
0,4 x 2 = 0,8 ... 0
0,8 x 2 = 1,6 ... 1
0,6 x 2 = 1,2 ... 1
0,2 x 2 = 0,4 ... 0
0,4 x 2 = 0,8 ... 0
0,8 x 2 = 1,6 ... 1
0,6 x 2 = 1,2 ... 1
Die erhaltenen Ganzzahlen sind von links nach rechts angeordnet: 000110011…

0,1 → 0,00011 (0011) ∞

0,2 x 2 = 0,4 ... 0
0,4 x 2 = 0,8 ... 0
0,8 x 2 = 1,6 ... 1
0,6 x 2 = 1,2 ... 1
0,2 x 2 = 0,4 ... 0
0,4 x 2 = 0,8 ... 0
0,8 x 2 = 1,6 ... 1
0,6 x 2 = 1,2 ... 1
0,2 x 2 = 0,4 ... 0
Die erhaltenen Ganzzahlen sind von links nach rechts angeordnet: 001100110…

0,2 → 0,00110 (0110) ∞

0,3 x 2 = 0,6 ... 0
0,6 x 2 = 1,2 ... 1
0,2 x 2 = 0,4 ... 0
0,4 x 2 = 0,8 ... 0
0,8 x 2 = 1,6 ... 1
0,6 x 2 = 1,2 ... 1
0,2 x 2 = 0,4 ... 0
0,4 x 2 = 0,8 ... 0
0,8 x 2 = 1,6 ... 1
Die erhaltenen Integer-Bits sind von links nach rechts 010011001… angeordnet.

0,3 → 0,01001 (1001) ∞

Die wissenschaftliche Notation wird einheitlich ausgedrückt als

0,1→0,00011(0011)∞→1,(1001)∞∗2 −4

0,2→0,00110(0110)∞→1,(1001)∞∗2 −3

0,3→0,01001(1001)∞→1,(0011)∞∗2 −2

Die doppeltgenaue Gleitkommazahl wird im Rechner gespeichert. Das Rot am Ende zeigt an, dass die Binärzahl die Mantisse überschreitet und daher aufgerundet werden muss.

Nach der 64-Bit-Speicherung mit doppelter Genauigkeit sieht die binäre Darstellung wie folgt aus
0,1 → 0 − 01111111011 − (1001) 12 1010

0,2 → 0 − 01111111100 − (1001) 12 1010

0,3 → 0 − 01111111101 − (0011) 12 0011

Zu diesem Zeitpunkt ist 0,1 + 0,20,1 + 0,20,1 + 0,20,1 + 0,2 nicht gleich 0,30,30,3

Deshalb bringen Zahlenberechnungen am Computer oft einige „Überraschungen“ mit sich!

Zusammenfassen

Dies ist das Ende dieses Artikels über Speicher und Variablenspeicher in JS. Weitere relevante Inhalte zu JS-Speicher und Variablenspeicher finden Sie in früheren Artikeln auf 123WORDPRESS.COM oder in den folgenden verwandten Artikeln. Ich hoffe, dass jeder 123WORDPRESS.COM in Zukunft unterstützen wird!

Das könnte Sie auch interessieren:
  • Detaillierte Erklärung von JS-Variablen, Umfang und Speicher
  • Ein kurzer Vortrag über Variablen, Umfang und Speicherprobleme in JavaScript
  • JavaScript-Variablen, Umfang und Speicher
  • Variablen, Umfang und Speicherprobleme in Javascript
  • Beispielanalyse des Gültigkeitsbereichs und der Speicherprobleme von JavaScript-Variablen

<<:  Detaillierte Erklärung gängiger Befehle in MySQL 8.0+

>>:  Notieren Sie einen Fehlerbehebungsbericht für die hohe CPU-Auslastung des Tomcat-Prozesses

Artikel empfehlen

Ausführliche Erläuterung der HTML-Grundlagen (Teil 2)

1. Liste Der Listen-UL- Container wird mit einer ...

JavaScript zum Erzielen eines Texterweiterungs- und -reduzierungseffekts

Die Implementierung des Erweiterns und Reduzieren...

Nginx-Proxy-Axios-Anforderung und Vorsichtsmaßnahmen

Vorwort Ich habe vor kurzem eine kleine Demo gesc...

MySQL 5.6 Installationsschritte mit Bildern und Text

MySQL ist ein Open-Source-Verwaltungssystem für k...

Layout im Vue.js-Stil Allgemeine Fähigkeiten zur Flutter-Geschäftsentwicklung

Korrespondenz zwischen Flutter und CSS im Shadow-...

Zwei Möglichkeiten zum Erstellen eines privaten GitLab mit Docker

Die erste Methode: Docker-Installation 1. Ziehen ...

VUE führt die Implementierung der Verwendung von G2-Diagrammen ein

Inhaltsverzeichnis Über G2 Chart verwenden Vollst...

Detaillierter Prozess der Installation von Logstash in Docker

Bearbeiten Sie docker-compose.yml und fügen Sie d...

Analyse des Prinzips und der Verwendung der kontinuierlichen MySQL-Aggregation

Dieser Artikel veranschaulicht anhand von Beispie...

MySQL-Datenbank implementiert OLTP-Benchmark-Test basierend auf Sysbench

Sysbench ist ein hervorragendes Benchmark-Tool, d...