Heim  >  Artikel  >  Web-Frontend  >  Einige wenige Kenntnisse über die Rechengenauigkeit in Javascript (Zusammenfassung)

Einige wenige Kenntnisse über die Rechengenauigkeit in Javascript (Zusammenfassung)

青灯夜游
青灯夜游Original
2018-09-17 15:07:042588Durchsuche

In diesem Kapitel werden Ihnen einige Grundkenntnisse (Zusammenfassung) über die Berechnungsgenauigkeit in JavaScript vermittelt, damit Sie verstehen, wie Binärzahlen in Dezimalzahlen umgewandelt werden, wie JavaScript Zahlen speichert, wie JavaScript Zahlen liest und schließlich anhand von Beispielen erläutert wird, wie das funktioniert Javascript löst Berechnungsfehler, die durch Präzisionsprobleme verursacht werden. Es hat einen gewissen Referenzwert. Freunde in Not können sich darauf beziehen. Ich hoffe, es wird Ihnen hilfreich sein.

1. Erforderliche Wissenspunkte

1. Wie konvertiert man Dezimalzahlen in Binärzahlen?

Teilen Sie den ganzzahligen Teil durch zwei und bilden Sie den Rest, bis der Quotient 0 ist. Ordnen Sie in umgekehrter Reihenfolge an. Multiplizieren Sie den Dezimalteil mit 2 und runden Sie in der Reihenfolge auf, bis der Dezimalteil des Produkts 0 ist die erforderliche Genauigkeit erreicht ist.

8转为二进制是多少?

8 / 2 = 4...0  取0
4 / 2 = 2...0  取0
2 / 2 = 1...0  取0
1 / 2 = 0...1  取1

二进制结果为:1000

0.25转为二进制是多少?

0.25 * 2 = 0.50  取0
0.50 * 2 = 1.00  取1

二进制结果为:01

于是可得出8.25的二进制表示:1000.01

2. Wie konvertiert man binär in dezimal?

Hinweis: Bei der Konvertierung von binär in dezimal werden der ganzzahlige Teil und der dezimale Teil nicht getrennt.

二进制1000.01转为十进制

1 * 2^3 + 0 * 2^2 + 0 * 2^1 + 0 * 2^0 + 0 * 2^-1 + 0 * 2^-2 = 8.25

2. Wie speichert Javascript Zahlen?

Die Zahlen in JavaScript sind 64-Bit-Gleitkommazahlen mit doppelter Genauigkeit der IEEE 754-Standard.

  • Vorzeichenbit (Vorzeichen): Wird zur Darstellung des positiven und negativen Vorzeichens verwendet, 1 Bit (0 bedeutet positiv, 1 bedeutet negativ)

  • Exponent( Exponent): Wird zur Darstellung der Potenz verwendet, 11 Ziffern

  • Mantisse (Mantisse): Wird zur Darstellung der Genauigkeit verwendet, 52 Ziffern

Einige wenige Kenntnisse über die Rechengenauigkeit in Javascript (Zusammenfassung)

Für diejenigen, die keinen Kontakt damit haben, ist das oben Gesagte möglicherweise vage zu verstehen. Als nächstes werden wir den Prozess anhand eines Falles im Detail erklären Schauen wir uns zunächst an, wie die oben genannte Dezimalzahl 8,25 in JS gespeichert wird.

  • Dezimal 8,25 wird in binär 1000,01 umgewandelt;

  • Binär 1000,01 kann durch die binäre wissenschaftliche Notation 1,00001 * 2^4 dargestellt werden; >

  • 00001 * Der Dezimalteil 00001 (binär) von 2^4 ist die Mantisse (Mantisse) und 4 (dezimal) plus 1023 ist der Exponent (Exponent) (ich werde später erklären, warum Add 1023);

  • Als nächstes muss der Exponent 4 zu 1023 addiert und in binär 10000000011 umgewandelt werden;

  • Unsere Dezimalzahl 8,25 ist positiv Zahl, daher wird das Symbol binär ausgedrückt als 0

  • 8,25 Die endgültige Binärspeicherung ist 0-10000000011-000010000000000000000000000000000000000000000000000

Hinweis:

  • Wir fügen 0 hinzu, wenn nicht genügend Ziffern vorhanden sind;

  • Wir scheinen den ganzzahligen Teil 1 in der wissenschaftlichen Notation, den wir in Schritt 2 erhalten haben, vergessen zu haben. Dies Dies liegt daran, dass Javascript zur Vereinfachung verwendet wird. Um die Genauigkeit zu maximieren, wird diese 1 weggelassen. Auf diese Weise können wir nur eine (binäre) 52-Bit-Mantisse speichern, aber es gibt tatsächlich 53 (binäre) Bits.

  • Der Exponententeil beträgt 11 Bits und der dargestellte Bereich ist [0, 2047], da der Exponent in der wissenschaftlichen Notation positiv oder negativ sein kann, die Zwischenzahl ist 1023, [0,1022] wird als negativ ausgedrückt, [1024,2047] wird als positiv ausgedrückt, Dies erklärt auch, warum der Exponent in unserer wissenschaftlichen Notation mit der Hinzufügung von 1023 gespeichert wird.

3. Wie liest Javascript Zahlen? 00000000000000000 Lass uns Sprechen Sie über

Zuerst erhalten wir die binäre 1000000001 des Exponententeils und wandeln sie in die Dezimalzahl 1027 um. 1027 minus 1023 ist unser tatsächlicher Exponent 4; 🎜>Erhalten Sie den Mantissenteil 0000100000000000000000000000000000000000000000 (die folgende 0 wird nicht geschrieben), und fügen Sie dann die 1 hinzu, die wir ignoriert haben, und erhalten Sie 1,00001;

  1. Weil das erste Stück ist 0, also ist unsere Zahl eine positive Zahl, also ist die binäre wissenschaftliche Notation 1,00001 * 2^4, und dann in eine Dezimalzahl umgewandelt, erhalten wir unsere 8,25; >

    4. Betrachtung von JavaScript-Genauigkeitsproblemen ab 0,1+0,2

  2. Nachdem wir die vorherige Prinziperklärung verstanden haben, wird dieser Teil sehr wichtig Gut. Verstanden.

  3. Um 0,1+0,2 zu berechnen, müssen Sie zuerst diese beiden Gleitkommazahlen lesen.
  4. 0,1 wird als binäre 64-Bit-Gleitkommazahl gespeichert.

  5. Habe das nicht vergessen obige Schritte

Zuerst 0,1 in den binären Ganzzahlteil in 0 umwandeln, und der Dezimalteil ist: 0001100110011001100110011001100110011... Hey, hier gibt es eine Endlosschleife, was soll ich tun? Ignorieren Sie es vorerst;

Die Endlosschleife der Binärzahlen wird in der wissenschaftlichen Notation ausgedrückt als 1.100110011001100110011001100110011... * 2^-4;

Das Exponentenbit ist -4 + 1023 = 1019 und das umgewandelte Bit ist eine 11-stellige Binärzahl 01111111011;

    Das Mantissenbit ist eine Endlosschleife, aber doppelt- Präzisions-Gleitkommazahlen erfordern 52 Bit Mantisse. Daher werden diejenigen, die 52 Bit überschreiten, weggelassen, und 1001100110011001100110011001100110011010
  1. wird schließlich als 64-Bit-Binär-Gleitkommazahl erhalten 0,1: 0-01111111011-1001 100110011001100110011001100110011001100110011010

同上,0.2存储为64位二进制浮点数:0-01111111100-1001100110011001100110011001100110011001100110011010

读取到两个浮点数的64为二进制后,再将其转化为可计算的二进制数

  1. 0.1转化为1.1001100110011001100110011001100110011001100110011010 * 2^(1019 - 1023)——0.00011001100110011001100110011001100110011001100110011010;

  2. 0.2转化为1.1001100110011001100110011001100110011001100110011010 * 2^(1020 - 1023)——0.0011001100110011001100110011001100110011001100110011010;

接着将两个浮点数的二进制数进行加法运算,得出0.0100110011001100110011001100110011001100110011001100111转化为十进制数即为0.30000000000000004

不难看出,精度缺失是在存储这一步就丢失了,后面的计算只是在不精准的值上进行的运算。

五. javascript如何解决精度问题出现的计算错误问题

对于小数或者整数的简单运算可如下解决:

function numAdd(num1, num2) { 
  let baseNum, baseNum1, baseNum2; 
  try { 
    baseNum1 = String(num1).split(".")[1].length; 
  } catch (e) { 
    baseNum1 = 0; 
  } 
  try { 
    baseNum2 = String(num2).split(".")[1].length; 
  } catch (e) { 
    baseNum2 = 0;
  } 
  baseNum = Math.pow(10, Math.max(baseNum1, baseNum2));
  return (num1 * baseNum + num2 * baseNum) / baseNum;
};

如:0.1 + 0.2 通过函数处理后,相当于 (0.1 * 10 + 0.2 * 10) / 10

但是如同我们前面所了解的,浮点数在存储的时候就已经丢失精度了,所以浮点数乘以一个基数仍然会存在精度缺失问题,比如2500.01 * 100 = 250001.00000000003, 所以我们可以在以上函数的结果之上使用toFixed(),保留需要的小数位数。

一些复杂的计算,可以引入一些库进行解决


Das obige ist der detaillierte Inhalt vonEinige wenige Kenntnisse über die Rechengenauigkeit in Javascript (Zusammenfassung). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn