Heim > Artikel > Backend-Entwicklung > Codeanalyse der Dezimalgenauigkeit in PHP
Der Inhalt dieses Artikels befasst sich mit der Codeanalyse der Dezimalgenauigkeit in PHP. Ich hoffe, dass er für Freunde hilfreich ist.
Beim Runden auf zwei Dezimalstellen im Projekt sind Genauigkeitsprobleme aufgetreten:
$num = 0.99; $num1 = round($num, 2);//0.98999999999999999 $num2 = floatval($num);//0.98999999999999999
Aktuelle Lösung:
sprintf("%.2f", round($money, 2));//会自动四舍五入 echo substr(sprintf("%.3f",$n), 0, -1);//不四舍五入
Testergebnisse:
var_dump(json_encode(round(0.99 ,2)));//0.98999999999999999 var_dump(round(0.99 ,2));//0.99 $f = 0.58; var_dump(intval($f * 100));//57
Ungefähr gleich 57 Wir können das Problem analysieren:
Darstellung von Gleitkommazahlen (IEEE 754: IEEE Binary Floating Point Arithmetic Standard):
Gleitkommazahlen unter Verwendung einer 64-Bit-Länge (doppelte Genauigkeit) als Beispiel: wird durch 1 Vorzeichenbit (E), 11 Exponentenbits (Q) und 52 Mantissen (M) (insgesamt 64 Bits) dargestellt.
Vorzeichenbit: Das höchste Bit gibt das Vorzeichen von an In den Daten bedeutet 0 eine positive Zahl, 1 bedeutet eine negative Zahl.
Exponentenbit: Stellt die Potenz der Daten mit Basis 2 dar, der Exponent wird durch den Offset-Code dargestellt
Mantisse: Stellt die signifikanten Stellen nach dem Dezimalpunkt der Daten dar
0,58 für die binäre Darstellung. Beispielsweise ist es ein unendlich langer Wert:
Die binäre Darstellung von 0,58 ist grundsätzlich (52 Bits): 0010100011110101110000101000111101011100001010001111
Die binäre Darstellung von. 0,57 ist im Grunde ( 52 Bits) ist: 001000111101011100001010001111010111000010100011110
Und die Binärzahlen der beiden, wenn sie nur mit diesen 52 Bits berechnet werden, sind:
0,58 -->. 0,5799999 999999996
0,57 --> 0,5699999999 999999
Das Ergebnis von 0,58 * 100 ist also: 57,999999999, umgewandelt in eine ganze Zahl: 57
Für die binäre Darstellung von Gleitkommazahlen können Sie sich auf Folgendes beziehen: Binäre Darstellung von Gleitkommazahlen Punktzahlen
Ähnlich wie:
(0.1 + 0.7) == 0.8//false floor((0.1+0.7)*10)//7 //内部结果可能是:7.9999999999 //所以:不可能精确的用有限位数表达某些十进制分数 1/3=3.33333333333 //而3.333333333333333*3,却不是1
Also Fazit:
Glauben Sie also niemals, dass das Gleitkommaergebnis bis zur letzten Ziffer genau ist, und vergleichen Sie niemals zwei Gleitkommazahlen Punktzahlen, um zu sehen, ob sie gleich sind. Wenn Sie wirklich eine höhere Präzision benötigen, sollten Sie mathematische Funktionen mit beliebiger Präzision oder GMP-Funktionen verwenden
Es wird empfohlen, hochpräzise Funktionen zu verwenden:
Hochpräzise Funktionen
bcadd – Addition von 2 Zahlen beliebiger Genauigkeit
bccomp – Vergleicht zwei Zahlen beliebiger Genauigkeit
bcp – Berechnen Sie die Division von 2 Zahlen beliebiger Genauigkeit
bcmod – Modulo einer Zahl beliebiger Genauigkeit
bcmul – Multiplikationsberechnung von 2 Zahlen mit beliebiger Genauigkeit
bcpow – die Potenz einer Zahl mit beliebiger Genauigkeit
bcpowmod – Erhöhen einer beliebigen Präzisionszahl auf eine andere, reduziert um einen angegebenen Modul
bcscale – Legen Sie die Standardanzahl der Dezimalstellen für alle bc-Mathefunktionen fest
bcsqrt – die Quadratwurzel einer Zahl mit beliebiger Genauigkeit
bcsub – die Subtraktion von 2 Zahlen mit beliebiger Genauigkeit
Verwenden Sie hochpräzise Funktionen, um Rundungen zu erreichen:
function getBcRound($number, $precision = 0) { $precision = ($precision < 0) ? 0 : (int) $precision; if (strcmp(bcadd($number, '0', $precision), bcadd($number, '0', $precision+1)) == 0) { return bcadd($number, '0', $precision); } if (getBcPresion($number) - $precision > 1) { $number = getBcRound($number, $precision + 1); } $t = '0.' . str_repeat('0', $precision) . '5'; return $number < 0 ? bcsub($number, $t, $precision) : bcadd($number, $t, $precision); } function getBcPresion($number) { $dotPosition = strpos($number, '.'); if ($dotPosition === false) { return 0; } return strlen($number) - strpos($number, '.') - 1; } $money = getBcRound(0.99, 2);
Empfohlene verwandte Artikel:
Parsen von AES-verschlüsselten Dateien in PHP (mit Code)
Code für Post-Methode anfordern und Methode in Curl von PHP abrufen
Über PHP Middle Key Content Analysis
Das obige ist der detaillierte Inhalt vonCodeanalyse der Dezimalgenauigkeit in PHP. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!