Maison > Article > développement back-end > Que dois-je faire si php ne peut pas calculer les nombres à virgule flottante ?
php ne peut pas calculer les nombres à virgule flottante car le binaire sous-jacent de l'ordinateur ne peut pas représenter avec précision les nombres à virgule flottante. La solution consiste à utiliser une bibliothèque de classes ou une bibliothèque de fonctions pour des calculs précis, comme la bibliothèque de fonctions de haute précision BC en php.
L'environnement d'exploitation de cet article : système Windows 7, PHP version 7.1, ordinateur DELL G3
Que dois-je faire si php ne peut pas calculer les nombres à virgule flottante ?
Problèmes avec le calcul des nombres à virgule flottante en php
Si vous utilisez +-*/ de php pour calculer les nombres à virgule flottante, vous pouvez rencontrer des problèmes avec des résultats de calcul incorrects, tels que echo intval(0.58*100); print 57, au lieu de 58. Il s'agit en fait d'un bug selon lequel le binaire sous-jacent de l'ordinateur ne peut pas représenter avec précision les nombres à virgule flottante. J'ai également rencontré ce problème en utilisant Python. Donc, fondamentalement, la plupart des langages fournissent des bibliothèques de classes ou des bibliothèques de fonctions pour des calculs précis. Par exemple, PHP dispose d'une bibliothèque de fonctions de haute précision BC. Voici quelques fonctions de haute précision BC couramment utilisées.
Exemple
<?php $f = 0.58; var_dump(intval($f * 100)); //为啥输出57 ?>
Pourquoi la sortie 57 ? Y a-t-il un bug en PHP ?
Je crois que de nombreux étudiants ont eu cette question, car beaucoup de gens me posent des questions similaires, sans parler des bugs.php. demandez sur le net...
Pour comprendre cette raison, il faut d'abord connaître la représentation des nombres à virgule flottante (IEEE 754) : Les nombres à virgule flottante, en prenant comme exemple une longueur de 64 bits (double précision), utiliseront 1 bit de signe (E), 11 bits d'exposant (Q), mantisse de 52 bits (M) représente (64 bits au total).
Bit de signe : Le bit le plus élevé représente le signe de la donnée, 0 représente un nombre positif, et 1 représente un nombre négatif.
Bit exposant : représente la puissance des données en base 2, et l'exposant est représenté par un code de décalage
Mantisse : représente les chiffres significatifs après la virgule décimale des données.
Le point clé ici est la représentation des décimales en binaire, qu'en est-il des décimales ? Exprimées en binaire, vous pouvez le rechercher sur Baidu. Je n'entrerai pas dans les détails ici. La chose clé que nous devons comprendre est que pour la représentation binaire, 0,58 est une valeur infiniment longue (la valeur binaire). Les nombres suivants omettent le 1 implicite). 100011110101 11000010100011110 Et les nombres binaires des deux, s'ils sont calculés uniquement à travers ces 52 bits, sont : www.111cn.net
0.58 -> 0.5799999999999999960.57 -> 0.5699999999999999 Quant à la multiplication spécifique à virgule flottante de 0,58 * 100, nous ne la considérerons pas en détail. ), on va voir ça vaguement avec du calcul mental... 0.58 * 100 = Alors, je ne pensais plus que c'était un bug PHP, mais voilà c'est ça...
Il y a une inexactitude dans + -*%/ dans le traitement PHP en virgule flottante
Par exemple :
$a = 0.1; $b = 0.7; var_dump(($a + $b) == 0.8);
La valeur imprimée est booléenne false
Pourquoi le manuel PHP contient-il le message d'avertissement suivant pour les nombres à virgule flottante :
Avertissement
Précision en virgule flottante
Apparemment, des fractions décimales simples comme 0,1 ou 0,7 ne peuvent pas être converties au format binaire interne sans perdre un peu de précision. Cela peut conduire à des résultats confus : par exemple, floor((0.1+0.7)*10) renverra généralement 7 au lieu du 8 attendu, car la représentation interne du résultat est quelque chose comme 7,9999999999….
Cela est lié au fait qu'il est impossible d'exprimer avec précision certaines fractions décimales avec un nombre limité de chiffres. Par exemple, 1/3 en décimal devient 0,3333333 .
Ne croyez donc jamais que le résultat du nombre à virgule flottante est précis jusqu'au dernier chiffre, et ne comparez jamais si deux nombres à virgule flottante sont égaux. Si vous avez vraiment besoin d'une plus grande précision, vous devez utiliser des fonctions mathématiques de précision arbitraire ou des fonctions gmp
Le code est le suivant :
<?php $a = 0.1; $b = 0.7; var_dump(bcadd($a,$b,2) == 0.8);
bcadd — 将两个高精度数字相加 bccomp — 比较两个高精度数字,返回-1, 0, 1 bcp — 将两个高精度数字相除 bcmod — 求高精度数字余数 bcmul — 将两个高精度数字相乘 bcpow — 求高精度数字乘方 bcpowmod — 求高精度数字乘方求模,数论里非常常用 bcscale — 配置默认小数点位数,相当于就是Linux bc中的”scale=” bcsqrt — 求高精度数字平方根 bcsub — 将两个高精度数字相减
Nous avons compilé quelques exemples
La bibliothèque de fonctions de haute précision php BC comprend : l'addition, la comparaison, la division, phase Soustraction, reste, multiplication, nième puissance, configurer le nombre par défaut de points décimaux, carré. Ces fonctions sont plus utiles lorsqu'il s'agit de calculs monétaires, tels que les calculs de prix du commerce électronique.
Remarque : concernant le nombre de chiffres définis, l'excédent est écarté au lieu d'être arrondi.
Apprentissage recommandé : "
Tutoriel vidéo PHP"
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!