Maison >développement back-end >tutoriel php >Une explication de la méthode de comparaison des nombres à virgule flottante PHP

Une explication de la méthode de comparaison des nombres à virgule flottante PHP

jacklove
jackloveoriginal
2018-06-09 10:32:341525parcourir

Problème de précision du fonctionnement en virgule flottante

Regardez d'abord un exemple :

<?php$a = 0.1;$b = 0.9;$c = 1;
var_dump(($a+$b)==$c);
var_dump(($c-$b)==$a);?>

$a+$b==$c renvoie true ,Correct
$c-$b==$a renvoiefalse,Erreur

Pourquoi est-ce ? Après l'opération
, le contenu réel renvoyé lorsque la précision est de 20 chiffres est le suivant :

<?php$a = 0.1;$b = 0.9;$c = 1;
printf("%.20f", $a+$b); // 1.00000000000000000000printf("%.20f", $c-$b); // 0.09999999999999997780?>

$c-$b vaut 0,09999999999999997780, donc comparer avec 0,1 renvoie false

Ce problème se produit car le calcul des nombres à virgule flottante implique de la précision. Lorsque les nombres à virgule flottante sont convertis en binaire, la précision peut être perdue.

Méthode de conversion de nombres à virgule flottante

La partie entière est divisée par 2 et le reste est pris MéthodeLa partie décimale est multipliée par 2 Arrondi
méthode

Par exemple :

Convertir le nombre 8,5 en binaire La partie entière est 8
8/2=4 8%2 =0 4/2=2 4%2=0
2/2=1 2%2=0
1 est plus petit que 2, il n'est donc pas nécessaire de le calculer Le système binaire de. l'entier 8 est
1000

La partie décimale est 0,5

0,5x2 = 1,0 Parce que la partie décimale après arrondi est 0, il n'y a pas besoin de calculer plus
Décimal 0,5 Le système binaire de 0,1

8,5 Le système binaire de

est 1000,1

Calculer le système binaire du nombre 0,9

0,9x2= 1,8 0,8x2=1,6
0,6x2=1,2
0,2x2=0,4
0,4x2=0,8
0,8x2= 1.6
…. Ensuite la boucle continue, lorsque la précision de l'interception est Lorsque N, le nombre après N sera arrondi, entraînant une perte de précision.
Dans l'exemple ci-dessus, la précision de 0,9 est perdue lors de la conversion en binaire, ce qui entraîne des erreurs lors de la comparaison.

Ne croyez donc jamais qu'un nombre à virgule flottante est précis jusqu'au dernier chiffre, et ne comparez jamais deux nombres à virgule flottante pour vérifier leur égalité.

Comment comparer correctement les nombres à virgule flottante

Utilisez la méthode ronde pour traiter puis comparer

Exemple :

<?php$a = 0.1;$b = 0.9;$c = 1;
var_dump(($c-$b)==$a);                   // falsevar_dump(round(($c-$b),1)==round($a,1)); // true?>
2. Utilisez des méthodes de calcul de haute précision


Lorsque vous effectuez d'abord des calculs, utilisez des méthodes de calcul de haute précision pour vous assurer que la précision n'est pas perdue. .
La méthode de fonctionnement de haute précision est la suivante :

bcadd Ajoutez deux nombres de haute précision
bccomp Comparez les deux nombres de haute précision, renvoient -1,0,1
bcp Divisez deux nombres de haute précision
bcmod Trouvez le reste d'un nombre de haute précision
bcmul Multipliez deux nombres de haute précision
bcpow Trouvez la puissance d'un nombre de haute précision
bcpowmod Trouvez la puissance et le module de un nombre de haute précision
bcscale Configurez le nombre de points décimaux par défaut, équivalent à "scale=" sous Linux bc
bcsqrt Trouvez la racine carrée d'un nombre de haute précision nombre de précision
bcsub Combinez deux soustractions de nombres de haute précision
Exemple :

Cet article explique la méthode de comparaison de nombres à virgule flottante PHP Pour plus d'informations. contenu, veuillez faire attention au site Web PHP chinois.

<?php$a = 0.1;$b = 0.9;$c = 1;
var_dump(($c-$b)==$a);          // falsevar_dump(bcsub($c, $b, 1)==$a); // true?>
Recommandations associées :

Explication de la méthode d'exportation des résultats de requête vers csv via mysql


php array_push et $arr [] Comparaison des performances entre =$value


Comment utiliser php pour configurer une session qui contrôle strictement le délai d'expiration

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn