Heim  >  Artikel  >  Backend-Entwicklung  >  PHP-Gleitkomma-Vergleichsmethode

PHP-Gleitkomma-Vergleichsmethode

WBOY
WBOYOriginal
2016-07-30 13:30:02925Durchsuche

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

Warum passiert das?

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.


Konvertierungsmethode für Gleitkommazahlen

Der ganzzahlige Teil übernimmt die Restmethode dividiert durch 2

Der Dezimalteil wird durch Multiplikation mit 2 gerundet

Zum Beispiel: Wandeln Sie die Zahl 8,5 in eine Binärzahl um


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,6x2=1,2

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:

2. Verwenden Sie hochpräzise Berechnungsmethoden

Verwenden Sie bei der ersten Berechnung hochpräzise Berechnungsmethoden, um sicherzustellen, dass die Genauigkeit nicht verloren geht.

Die Methode der hochpräzisen Bedienung ist wie folgt:

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

bcmul Multiplizieren Sie zwei hochpräzise Zahlen
<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>
bcpow findet die Kraft hochpräziser Zahlen

bcpowmod ermittelt hochpräzise numerische Potenz und Modul
bcscale konfiguriert die Standardanzahl der Dezimalstellen, was „scale=" in Linux bc

entspricht bcsqrt ermittelt die Quadratwurzel einer hochpräzisen Zahl

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.

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
Vorheriger Artikel:Objektorientiert in PHPNächster Artikel:Objektorientiert in PHP