Position actuelle: Accueil> Derniers articles> Est-il sûr d'utiliser array_diff () pour traiter les tableaux de points flottants?

Est-il sûr d'utiliser array_diff () pour traiter les tableaux de points flottants?

M66 2025-06-06

Dans PHP, Array_Diff () est une fonction très pratique pour comparer les tableaux et les différences de retour. Il compare les valeurs pour découvrir des éléments dans le premier tableau mais pas dans d'autres tableaux. Ce n'est généralement pas un problème avec le traitement des chaînes et des entiers, mais lorsqu'il s'agit de tableaux à virgule flottante, un comportement "inattendu" peut se produire, en raison de nombres à virgule flottante.

Utilisation de base de Array_Diff ()

Commençons par un exemple simple:

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

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

La sortie est:

 Array
(
    [0] => 1.1
)

Ce résultat est conforme aux attentes. Cependant, dans certains cas, les nombres de points flottants peuvent entraîner des erreurs par rapport à array_diff () en raison de limitations de précision.

Problèmes causés par la précision des points flottants

Les nombres à virgule flottante ne peuvent pas représenter avec précision certaines décimales dans les ordinateurs, et il peut y avoir de légères erreurs. Par exemple:

 <?php
$a = [0.1 + 0.2]; // La valeur réelle est 0.30000000000000004
$b = [0.3];

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

La sortie est:

 Array
(
    [0] => 0.30000000000000004
)

Vous pourriez penser 0,1 + 0,2 == 0,3 , mais la représentation du point flottant binaire à l'intérieur de l'ordinateur rend cette équation non toujours vraie. Cela signifie que Array_Diff () tiendra compte des deux valeurs pas égales , ce qui entraînera une erreur de jugement.

Pourquoi Array_Diff () échoue-t-il?

La couche sous-jacente de Array_Diff () est basée sur une comparaison lâche ( == ) pour déterminer si les deux valeurs sont égales. Mais le problème de précision des nombres à virgule flottante lui-même signifie que même si deux nombres sont logiquement "égaux", leurs représentations en mémoire peuvent être différentes, surtout après que des calculs décimaux soient impliqués.

Race à la sécurité: erreurs de jugement des données

Dans le traitement des données financières, des données de capteurs ou d'autres scénarios commerciaux qui nécessitent des calculs précis, ce comportement de Array_Diff () peut conduire à:

  • Identifier à tort si les données existent

  • Erreurs logiques dans la branche judiciaire commerciale

  • Impossible de synchroniser ou de comparer correctement les différences de données

Il s'agit non seulement d'un bogue de code, mais peut même être un problème de sécurité commerciale .

Solution: utilisez une logique de comparaison personnalisée

PHP fournit Array_udiff () , qui permet aux développeurs de fournir leurs propres fonctions de comparaison, qui peuvent implémenter une logique de différence de point flottante plus sûre:

 <?php
function float_compare($a, $b) {
    $epsilon = 0.00001; // Tolérance à la précision
    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);

La sortie est:

 Array
(
)

Cette fois, array_udiff () identifie correctement que les deux sont "égaux", évitant les problèmes causés par l'erreur de point flottante.

Conseils: une autre façon d'assurer une précision cohérente

Lorsque vous ne pouvez pas utiliser array_udiff () ou des fonctions personnalisées, il existe également une méthode "Curve enregistre le pays" pour formater les numéros de point flottants:

 $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);

Cette méthode peut également éviter efficacement la plupart des problèmes causés par la précision, mais il doit encore être utilisé avec prudence.

Résumer

Lorsque vous utilisez Array_Diff () pour traiter les tableaux de points flottants, une attention particulière doit être accordée au mécanisme de traitement PHP sur les nombres de points flottants, en particulier l'impact des erreurs de précision. Si les nombres à virgule flottante sont directement comparés, cela peut entraîner des erreurs logiques et même des risques de sécurité. Pour garantir la précision des données, il est recommandé d'utiliser Array_udiff () avec une fonction de comparaison de tolérance de précision personnalisée, ou d'effectuer un formatage unifié des données.

Dans les entreprises impliquant des données importantes, toute erreur apparemment mineure ne doit pas être ignorée.