Maison > Article > développement back-end > Problème de calcul de précision PHP
Problème de calcul de précision php
Jetons un coup d'œil à un phénomène intéressant en PHP : var_dump( intval(0.58 * 100 ) ); Devinez quel résultat ce code produira ?
Le résultat de sortie est 57, pas 58
Pourquoi ça ? Tout cela est dû à l'arithmétique à virgule flottante.
En fait, ces résultats ne sont pas des bugs de langage, mais sont liés au principe d'implémentation du langage. Tous les nombres en js sont unifiés en tant que Nombre, y compris les entiers, qui sont en fait tous des types doubles.
Et PHP fera la distinction entre int et float. Quelle que soit la langue, tant que des opérations en virgule flottante sont impliquées, il existe des problèmes similaires, vous devez donc y prêter attention lorsque vous les utilisez.
Les nombres à virgule flottante, prenant comme exemple une longueur de 64 bits (double précision), seront représentés par 1 bit de signe (E), 11 bits d'exposant (Q) et 52 bits de mantisse (M) ( 64 bits au total).
Bit de signe : le bit le plus élevé représente le signe des données, 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 décalé
Mantisse : représente les chiffres significatifs après la virgule décimale des données.
Les points clés ici Cela réside dans la représentation des décimales en binaire. Concernant la façon de représenter les décimales en binaire, vous pouvez effectuer une recherche sur Baidu. Je n'entrerai pas dans les détails ici. La chose clé que nous devons comprendre est celle-ci. représentation binaire, 0,58 est une valeur infinie (les nombres ci-dessous en omettant le 1 implicite). 0,57 est en gros (52 bits) : 0 01000111101011100001010001111010111000010100011110
Les nombres binaires des deux, s'ils sont calculés uniquement à partir de ces 52 bits, sont :
0,58 -> 99999960,57 -> 0,56999999999999999
Quant à 0,58 * 100 Nous ne réfléchissons pas en détail à la multiplication spécifique des nombres à virgule flottante. Nous la regardons simplement vaguement avec le calcul mental... 0,58 * 100 = 57,999999999
Alors si vous l'intégrez, ce sera naturellement 57...
On voit que, Le point clé de ce problème est : "Vous semblez avoir une décimale finie, mais elle est infinie dans la représentation binaire de l'ordinateur"
Il y a une inexactitude dans +-*%/ dans le type à virgule flottante PHP
Nous pouvons résoudre le problème des opérations en virgule flottante inexactes grâce aux éléments suivants couramment utilisés : fonctions de précision :bcadd — Ajoutez deux nombres de haute précision bccomp — Comparez deux nombres de haute précision, renvoyez -1, 0, 1
bcdiv — Diviser deux nombres de haute précision
bcmod — Trouver le reste d'un nombre de haute précision
bcmul — Multiplier deux nombres de haute précision
bcpow — Trouver la puissance d'un nombre de haute précision
bcpowmod — Trouver la puissance d'un nombre de haute précision et le moduler, très couramment utilisé en théorie des nombres
bcscale — configurer le nombre de points décimaux par défaut, équivalent à " scale=" sous Linux bc
bcsqrt — trouver la racine carrée d'un nombre de haute précision
bcsub — combiner deux nombres de haute précision Moins
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!