Problem mit der Genauigkeit der Gleitkommaoperation
Sehen Sie sich zunächst ein Beispiel an:
<code><span><span><?php</span><span>$a</span> = <span>0.1</span>; <span>$b</span> = <span>0.9</span>; <span>$c</span> = <span>1</span>; var_dump((<span>$a</span>+<span>$b</span>)==<span>$c</span>); var_dump((<span>$c</span>-<span>$b</span>)==<span>$a</span>); <span>?></span></span></code>
$a $b== $c gibt wahr zurück, richtig
$c-$b==$a gibt falsch,Fehler
Nach der Operation lautet der tatsächlich zurückgegebene Inhalt bei einer Genauigkeit von 20 Ziffern wie folgt:
<code><span><span><?php</span><span>$a</span> = <span>0.1</span>; <span>$b</span> = <span>0.9</span>; <span>$c</span> = <span>1</span>; printf(<span>"%.20f"</span>, <span>$a</span>+<span>$b</span>); <span>// 1.00000000000000000000</span> printf(<span>"%.20f"</span>, <span>$c</span>-<span>$b</span>); <span>// 0.09999999999999997780</span><span>?></span></span></code>
$c-$b ist 0,09999999999999997780, also gibt ein Vergleich mit 0,1 false
zurück. Dieses Problem tritt auf, weil die Berechnung von Gleitkommazahlen Präzision erfordert. Wenn Gleitkommazahlen in Binärzahlen konvertiert werden, kann die Genauigkeit verloren gehen.
Der Dezimalteil wird durch Multiplikation mit 2 gerundet
Der ganzzahlige Teil ist 8
8/2=4 8%2=0
4/2=2 4%2=0
2/2=1 2%2=0
1 ist kleiner als 2, daher ist keine Berechnung erforderlich. Die binäre Darstellung der ganzen Zahl 8 ist
1000
Der Dezimalteil ist 0,5
0,5x2 = 1,0
Da der Dezimalteil nach dem Runden 0 ist, ist keine weitere Berechnung erforderlich
Das Binärsystem der Dezimalzahl 0,5 ist 0,1
0,9x2=1,8
0,8x2=1,6
0,2x2=0,4 0,4x2=0,8 0,8x2=1,6 .... Dann wird die Schleife fortgesetzt. Wenn die Abfanggenauigkeit N beträgt, werden die Zahlen nach N gerundet, was zu einem Genauigkeitsverlust führt. Im obigen Beispiel geht die Genauigkeit von 0,9 bei der Konvertierung in Binärwert verloren, was zu Fehlern beim Vergleich führt.
Vertrauen Sie also niemals darauf, dass eine Gleitkommazahl bis zur letzten Ziffer genau ist, und vergleichen Sie niemals zwei Gleitkommazahlen auf Gleichheit.
So vergleichen Sie Gleitkommazahlen richtig
1. Verwenden Sie die Rundungsmethode zum Verarbeiten und anschließenden Vergleichen
Beispiel:
Verwenden Sie bei der ersten Berechnung hochpräzise Berechnungsmethoden, um sicherzustellen, dass die Genauigkeit nicht verloren geht.
bcadd fügt zwei hochpräzise Zahlen hinzu
bccomp vergleicht zwei hochpräzise Zahlen und gibt -1,0,1 zurück
bcdiv dividiert zwei hochpräzise Zahlen
bcmod findet hochpräzisen numerischen Rest
<code><span><span><?php</span><span>$a</span> = <span>0.1</span>; <span>$b</span> = <span>0.9</span>; <span>$c</span> = <span>1</span>; var_dump((<span>$c</span>-<span>$b</span>)==<span>$a</span>); <span>// false</span> var_dump(round((<span>$c</span>-<span>$b</span>),<span>1</span>)==round(<span>$a</span>,<span>1</span>)); <span>// true</span><span>?></span></span></code>
bcpowmod ermittelt hochpräzise numerische Potenz und Modul
bcscale konfiguriert die Standardanzahl der Dezimalstellen, was „scale=" in Linux bc
bcsub Subtrahieren Sie zwei hochpräzise Zahlen
Beispiel:
Copyright-Erklärung: Dieser Artikel ist ein Originalartikel des Bloggers und darf nicht ohne die des Bloggers reproduziert werden Erlaubnis.
Das Obige stellt die Vergleichsmethode für PHP-Gleitkommazahlen vor, einschließlich einiger Aspekte des Inhalts. Ich hoffe, dass es für Freunde hilfreich ist, die sich für PHP-Tutorials interessieren.