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

Natives js zur Realisierung der Bild-Upload-Steuerung

In diesem Artikelbeispiel wird der spezifische Co...

Implementierung einer Login-Seite basierend auf layui

In diesem Artikelbeispiel wird der spezifische Co...

Vue implementiert Div-Rad zum Vergrößern und Verkleinern

Implementieren Sie das Vergrößern und Verkleinern...

Beispiel für das Schreiben von mobilem H5 zum Aufrufen einer APP (IOS, Android)

iOS 1. URL-Schema Diese Lösung ist grundsätzlich ...

Der eigentliche Prozess der Implementierung des Zahlenrätsels im WeChat-Applet

Inhaltsverzeichnis Funktionseinführung Rendern 1....

Detaillierte Erklärung der Set-Datenstruktur von JavaScript

Inhaltsverzeichnis 1. Was ist Set 2. Konstruktor ...

Einfaches MySQL-Beispiel zum Sortieren chinesischer Schriftzeichen nach Pinyin

Wenn das Feld, in dem der Name gespeichert ist, d...

Detaillierte Beispiele zur Float-Verwendung in HTML/CSS

1. Grundlegende Anwendungsbeispiele für Float 1. ...

So stoppen Sie die CSS-Animation mittendrin und behalten die Haltung bei

Vorwort Ich bin einmal auf ein schwieriges Proble...

So migrieren Sie SQLite zu einem MySQL-Skript

Ohne weitere Umschweife werde ich den Code direkt...

Detaillierte Konfiguration von Nginx, das sowohl Http als auch Https unterstützt

Heutzutage gehört die Unterstützung von HTTPS für...