Maison  >  Article  >  développement back-end  >  Comment comparer des nombres à virgule flottante en php ?

Comment comparer des nombres à virgule flottante en php ?

怪我咯
怪我咯original
2017-07-11 13:58:494096parcourir

Les nombres à virgule flottante comporteront des erreurs pendant le processus de conversion, de sorte que les nombres à virgule flottante ne peuvent pas être comparés directement. Généralement, lors de la comparaison de deux nombres à virgule flottante, la différence entre eux est comparée si la différence entre les deux nombres est inférieure. une plage acceptable, alors nous considérons que les deux nombres à virgule flottante sont égaux. Cet article présente principalement la méthode de comparaison de nombres à virgule flottante php, qui a une bonne valeur de référence. Jetons-y un coup d'œil avec l'éditeur ci-dessous

Le problème de précision des opérations en virgule flottante

Regardons 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 vrai, correct
$c-$b==$a renvoie faux, faux

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.00000000000000000000
printf("%.20f", $c-$b); // 0.09999999999999997780
?>

$c-$b est 0,09999999999999997780, donc comparez avec 0,1 et retournez 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 d'un nombre à virgule flottante en binaire

La partie entière adopte le divisé par 2 pour prendre le reste méthode

La partie décimale est arrondie selon la méthode multipliée par 2

Par exemple : Convertissez 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 de l'entier 8 est 1000

La partie décimale est 0,5

0,5x2 = 1,0

Parce que la partie décimale est 0 après arrondi, il n'est plus nécessaire de calculer

Le système binaire de la décimale 0,5 est 0,1

8,5 Le système binaire de est 1000,1

Calculer le nombre 0,9 Binaire

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. est N, le nombre après N sera arrondi, ce qui entraînera 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);          // false
var_dump(round(($c-$b),1)==round($a,1)); // true
?>

2. Utiliser des méthodes de calcul de haute précision

Lors de l'exécution de calculs tout d'abord, utilisez des méthodes de calcul de haute précision Méthode de calcul de précision, afin de garantir que la précision n'est pas perdue.

La méthode de fonctionnement de haute précision est la suivante :

bcadd Convertir deux nombres de haute précision Ajouter

bccomp Compare deux nombres de haute précision, renvoie -1,0,1

bcp Diviser deux nombres de haute précision

bcmod Trouver 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 Trouver le module de la puissance des nombres de haute précision

bcscale Configurer le nombre de décimales par défaut , ce qui équivaut à Linux en bc ”scale=”

bcsqrt Trouver la racine carrée d'un nombre de haute précision

bcsub Combiner deux Soustraction numérique de haute précision

Exemple :

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