Maison > développement back-end > tutoriel php > Ce que vous devez savoir sur les nombres à virgule flottante PHP

Ce que vous devez savoir sur les nombres à virgule flottante PHP

藏色散人
Libérer: 2023-04-07 20:56:02
avant
2419 Les gens l'ont consulté

Vous devez savoir tous les « faux » sur le float en PHP (Tous les « faux » sur le float en PHP)

PHP est un langage faiblement typé. De telles fonctionnalités doivent être requises de manière transparente. conversion de type implicite transparente, PHP utilise zval en interne pour enregistrer tout type de valeur. La structure de zval est la suivante (5.2 à titre d'exemple) :

struct _zval_struct {
    /* Variable information */
    zvalue_value value;     /* value */
    zend_uint refcount;
    zend_uchar type;    /* active type */
    zend_uchar is_ref;
};
Copier après la connexion

Dans la structure ci-dessus, la valeur réelle elle-même est enregistrée par le. zvalue_value union. :

typedef union _zvalue_value {
    long lval;                  /* long value */
    double dval;                /* double value */
    struct {
        char *val;
        int len;
    } str;
    HashTable *ht;              /* hash table value */
    zend_object_value obj;
} zvalue_value;
Copier après la connexion

Le sujet d'aujourd'hui, nous nous concentrons uniquement sur deux membres, lval et dval. Nous devons réaliser que long lval a une longueur indéfinie en fonction de la longueur des mots du compilateur et du système d'exploitation. être 32 bits ou 64 bits, et le double dval (double précision) est stipulé par IEEE 754. Il est de longueur fixe et doit être de 64 bits

N'oubliez pas ceci, ce qui rend certains codes PHP "non indépendants de la plate-forme" "propriété. ". Notre discussion suivante, sauf indication contraire, suppose que long est une méthode de comptage à virgule flottante 64 bits

IEEE 754. Je ne la citerai pas ici. Si vous êtes intéressé, vous pouvez le vérifier par vous-même. La clé Un point est que la mantisse du double est stockée sur 52 bits en comptant le 1 bit significatif caché, le total est de 53 bits.

Ici, une question intéressante se pose. Utilisons le code c comme exemple ( en supposant que long est de 64 bits) :

  long a = x;
    assert(a == (long)(double)a);
Copier après la connexion

Excusez-moi, lorsque la valeur de a se situe dans quelle plage, le code ci-dessus peut être considéré comme réussi (Laissez la réponse à la fin de l'article)

Revenons maintenant au sujet PHP Avant d'exécuter un script, vous devez d'abord lire le script et l'analyser. Ce processus inclut également la zvalisation des littéraux dans le script. Par exemple, pour le script suivant :

.
<?php
$a = 9223372036854775807; //64位有符号数最大值
$b = 9223372036854775808; //最大值+1
var_dump($a);
var_dump($b);
Copier après la connexion

Sortie :

int(9223372036854775807)
float(9.22337203685E+18)
Copier après la connexion

En d'autres termes, lors de l'étape d'analyse lexicale, PHP jugera si une valeur littérale dépasse la longue plage de valeurs de la table du système actuel. Sinon, lval sera utilisé pour sauvegarder. et zval sera IS_LONG, sinon utilisez simplement dval pour le représenter, zval IS_FLOAT.

Nous devons être prudents avec toute valeur supérieure à la plus grande valeur entière, car elle peut entraîner une perte de précision :

<?php
$a = 9223372036854775807;
$b = 9223372036854775808;
 
var_dump($a === ($b - 1));
Copier après la connexion

Le résultat est faux.

Poursuivons maintenant la discussion au début, comme mentionné précédemment, les entiers de PHP peuvent être de 32 bits ou 64 bits, il est donc décidé que certains codes qui peuvent s'exécuter normalement sur 64 bits peut échouer en raison d'une conversion de type invisible entraînant une perte de précision, empêchant le code de fonctionner correctement sur les systèmes 32 bits

Par conséquent, nous devons nous méfier de cette valeur critique. a été défini en PHP :

<?php
    echo PHP_INT_MAX;
 ?>
Copier après la connexion

Bien sûr, pour être sûr, nous devons utiliser des chaînes pour enregistrer de grands entiers et utiliser des bibliothèques de fonctions mathématiques telles que bcmath pour effectuer des calculs.

De plus, il existe une configuration clé qui nous rendra confus. Cette configuration est php.precision. Cette configuration détermine le nombre de bits significatifs que PHP génère lorsqu'il génère une valeur flottante.

Enfin, revenons sur la question soulevée. ci-dessus, qui est un long Quelle est la valeur maximale d'un entier pour garantir que la précision ne sera pas perdue lorsqu'il est converti en float puis reconverti en long ?

Par exemple, pour un entier, nous savons que sa représentation binaire est 101. Maintenant, décalons deux bits vers la droite pour devenir 1,01, supprimons le bit significatif implicite 1 du bit haut, et nous obtenons la valeur binaire de 5 stockée dans le double :

0/*符号位*/ 10000000001/*指数位*/ 0100000000000000000000000000000000000000000000000000
Copier après la connexion

La représentation binaire de 5, qui est enregistrée dans la partie La mantisse, dans ce cas, est convertie de double back en long sans perte de précision.

Nous savons que double utilise 52 bits pour représenter la mantisse . En comptant le premier 1 implicite, il y a un total de 53 bits de précision. On peut alors conclure que si la valeur d'un entier long est inférieure à :

2^53 - 1 == 9007199254740991; //牢记, 我们现在假设是64bits的long
Copier après la connexion

, alors cet entier ne perdra pas en précision lorsque. la conversion de valeur long->double->long se produit

Recommandé : "Tutoriel 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!

Étiquettes associées:
source:laruence.com
Déclaration de ce site Web
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
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal