Aktueller Standort: Startseite> Neueste Artikel> Ist es sicher, Array_Diff () zu verwenden, um schwimmende Punktarrays zu verarbeiten?

Ist es sicher, Array_Diff () zu verwenden, um schwimmende Punktarrays zu verarbeiten?

M66 2025-06-06

In PHP ist Array_Diff () eine sehr praktische Funktion zum Vergleich von Arrays und Rückgabeunterschieden. Es vergleicht Werte, um Elemente im ersten Array zu finden, jedoch nicht in anderen Arrays. Dies ist normalerweise kein Problem mit der Verarbeitung von Strings und Ganzzahlen, aber im Umgang mit schwimmenden Punkt-Arrays kann ein "unerwartetes" Verhalten auftreten, da schwimmende Punkte.

Grundlegende Verwendung von Array_Diff ()

Beginnen wir mit einem einfachen Beispiel:

 <?php
$a = [1.1, 2.2, 3.3];
$b = [2.2, 3.3];

$result = array_diff($a, $b);
print_r($result);

Die Ausgabe ist:

 Array
(
    [0] => 1.1
)

Dieses Ergebnis steht im Einklang mit den Erwartungen. In einigen Fällen können jedoch schwimmende Punktzahlen zu Fehlern im Vergleich von Array_Diff () aufgrund von Präzisionsbeschränkungen führen.

Probleme, die durch die Genauigkeit der schwimmenden Punkte verursacht werden

Schwimmpunktzahlen können bestimmte Dezimalstellen in Computern nicht genau darstellen, und es kann zu geringfügigen Fehlern kommen. Zum Beispiel:

 <?php
$a = [0.1 + 0.2]; // Der tatsächliche Wert ist 0.30000000000000004
$b = [0.3];

$result = array_diff($a, $b);
print_r($result);

Die Ausgabe ist:

 Array
(
    [0] => 0.30000000000000004
)

Sie denken vielleicht , 0,1 + 0,2 == 0,3 , aber die binäre schwimmende Punktdarstellung im Computer macht diese Gleichung nicht immer zu. Dies bedeutet, dass array_diff () die beiden Werte nicht gleich betrachtet, was zu einer Fehleinschätzung führt.

Warum scheitert Array_Diff ()?

Die zugrunde liegende Schicht von Array_Diff () basiert auf losen Vergleich ( == ), um festzustellen, ob die beiden Werte gleich sind. Das Genauigkeitsproblem der Floating-Punkt-Zahlen selbst bedeutet jedoch, dass auch wenn zwei Zahlen logisch "gleich" sind, ihre Darstellungen im Gedächtnis unterschiedlich sein können, insbesondere wenn Dezimalberechnungen beteiligt sind.

Sicherheitsrisiko: Datenbeurteilungsfehler

Bei der Verarbeitung von Finanzdaten, Sensordaten oder anderen Geschäftsszenarien, die präzise Berechnungen erfordern, kann dieses Verhalten von array_diff () zu:

  • Identifizieren Sie falsch, ob die Daten vorhanden sind

  • Logische Fehler in der Filiale für Geschäftsverurteilungen

  • Datenunterschiede nicht korrekt synchronisieren oder vergleichen

Dies ist nicht nur ein Codefehler, sondern kann auch ein Problem mit der geschäftlichen Sicherheit sein.

Lösung: Verwenden Sie benutzerdefinierte Vergleichslogik

PHP bietet Array_udiff () , mit dem Entwickler ihre eigenen Vergleichsfunktionen bereitstellen können, die eine sicherere schwimmende Punktdifferenzlogik implementieren können:

 <?php
function float_compare($a, $b) {
    $epsilon = 0.00001; // Genauigkeitstoleranz
    if (abs($a - $b) < $epsilon) {
        return 0;
    }
    return ($a < $b) ? -1 : 1;
}

$a = [0.1 + 0.2];
$b = [0.3];

$result = array_udiff($a, $b, 'float_compare');
print_r($result);

Die Ausgabe ist:

 Array
(
)

Diesmal identifiziert Array_udiff () korrekt, dass die beiden "gleich" sind und die Probleme vermeiden, die durch einen schwimmenden Punktfehler verursacht werden.

Tipps: Eine andere Möglichkeit, eine konsistente Genauigkeit zu gewährleisten

Wenn Sie Array_udiff () oder benutzerdefinierte Funktionen nicht verwenden können, gibt es auch eine Methode "Kurve rettet das Land", um schwimmende Punktzahlen zu formatieren:

 $a = array_map(function($v) {
    return round($v, 5);
}, [0.1 + 0.2]);

$b = array_map(function($v) {
    return round($v, 5);
}, [0.3]);

$result = array_diff($a, $b);
print_r($result);

Diese Methode kann auch effektiv die meisten durch Genauigkeit verursachten Probleme vermeiden, muss jedoch noch mit Vorsicht verwendet werden.

Zusammenfassen

Bei der Verwendung von Array_Diff () zur Verarbeitung von schwimmenden Punktarrays sollte dem PHP -Verarbeitungsmechanismus auf schwimmende Punktzahlen besondere Aufmerksamkeit geschenkt werden, insbesondere auf die Auswirkungen von Genauigkeitsfehlern. Wenn Gleitkomma-Nummern direkt verglichen werden, kann dies zu logischen Fehlern und sogar zu Sicherheitsrisiken führen. Um die Datengenauigkeit sicherzustellen, wird empfohlen, Array_udiff () mit einer benutzerdefinierten Genauigkeitsvergleichsfunktion zu verwenden oder eine einheitliche Formatierung der Daten durchzuführen.

In Unternehmen mit wichtigen Daten sollte ein scheinbar geringfügiger Fehler nicht ignoriert werden.