Maison  >  Article  >  développement back-end  >  Problème de calcul de précision PHP

Problème de calcul de précision PHP

单线程
单线程original
2020-05-07 15:35:03160parcourir

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!

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