Les opérations en virgule flottante en PHP sont-elles exactes ?

青灯夜游
Libérer: 2023-03-17 17:38:01
original
3557 Les gens l'ont consulté

Non, il y a une erreur dans le fonctionnement en virgule flottante sous PHP. En PHP, les nombres à virgule flottante ont une précision limitée ; bien que selon le système, PHP utilise généralement le format double précision IEEE 754, l'erreur relative maximale due à l'arrondi est de « 1.11e-16 » ; les opérations mathématiques non basiques peuvent donner un A plus grand ; une erreur se produira et la propagation de l'erreur lors de l'exécution d'opérations composites doit être prise en compte.

Les opérations en virgule flottante en PHP sont-elles exactes ?

L'environnement d'exploitation de ce tutoriel : système Windows 7, version PHP 8, ordinateur DELL G3

Le "pot" des opérations sur les nombres à virgule flottante

//加
$a = 0.1;
$b = 0.7;
$c = intval(($a + $b) * 10);
echo $c."<br>";
//输出:7

//减
$a = 100;
$b = 99.98;
$c = $a - $b;
echo $c."<br>";
//输出:0.019999999999996

//乘
$a = 0.58;
$b = 100;
$c = intval($a * $b);
echo $c."<br>";
//输出:57

//除
$a = 0.7;
$b = 0.1;
$c = intval($a / $b);
echo $c."<br>";
//输出:6
Copier après la connexion

Les résultats ci-dessus ne sont évidemment pas ceux que nous souhaitons !

Le manuel PHP officiel l'explique comme suit :

Les nombres à virgule flottante ont une précision limitée. Bien que cela dépende du système, PHP utilise généralement le double format IEEE 754, donc l'erreur relative maximale due à l'arrondi est de 1.11e-16. Les opérations mathématiques non fondamentales peuvent donner lieu à des erreurs plus importantes, et la propagation des erreurs lors de l'exécution d'opérations composées doit être prise en compte. Ne faites jamais confiance à un résultat à virgule flottante jusqu'au dernier chiffre et ne comparez jamais deux nombres à virgule flottante pour vérifier leur égalité. Si vous avez vraiment besoin d'une plus grande précision, vous devez utiliser la fonction mathématique de précision arbitraire ou la fonction gmp.

La clé ici est que la décimale d'un nombre à virgule flottante est exprimée en binaire. Le processus est le suivant :

  • Multipliez la décimale par 2 et prenez la partie entière pour représenter le premier chiffre ; partie par 2 et prenez la partie entière pour représenter Le deuxième chiffre
  • Puis multipliez la partie décimale par 2, et prenez la partie entière pour représenter le troisième chiffre
  • ... et ainsi de suite jusqu'à ce que la partie décimale soit 0 ;
  • Exemple : 0,58

0,58 * 2 = 1,16 ---> 1
  • 0,16 * 2 = 0,32 ---> 4* 2 = 1,28 ---> 1
  • 0,28 * 2 = 0,56 ---> 0
  • 0,56 * 2 = 1,12 ---> 0,24 * 2 = 0,48 ---> 0
  • 0,48 * 2 = 0,96 ---> 0
  • 0,96 * 2 = 1,92 ---> boucle de décimales binaires :
  • 0.1001010001...
  • Décimale Certaines boucles apparaissent et les bits binaires limités ne peuvent pas représenter avec précision une décimale. C'est la raison des erreurs dans les opérations décimales.
  • Ensuite, je vais vous présenter les
  • fonctions mathématiques de précision arbitraire
  • .
  • Fonctions mathématiques de précision arbitraire
Pour les mathématiques de précision arbitraire, PHP fournit des calculs binaires qui prennent en charge des nombres de toute taille et précision représentés par des chaînes.

BCMath : BC est l'abréviation de Binary Calculator.

Manuel officiel :

http://php.net/manual/zh/book.bc.php

Veuillez confirmer si bcmath a été installé avant de l'utiliser.

//加
$a = 0.1;
$b = 0.7;
$c = intval(bcadd($a, $b, 1) * 10);
echo $c."<br>";
//输出:8

//减
$a = 100;
$b = 99.98;
$c = bcsub($a, $b, 2);
echo $c."<br>";
//输出:0.02

//乘
$a = 0.58;
$b = 100;
$c = intval(bcmul($a, $b));
echo $c."<br>";
//输出:58

//除
$a = 0.7;
$b = 0.1;
$c = intval(bcdiv($a, $b));
echo $c."<br>";
//输出:7
Copier après la connexion
En plus de l'addition, de la soustraction, de la multiplication et de la division, bcmath fournit également les méthodes suivantes :

bccomp Compare deux nombres à précision arbitraire

bcmodulo un nombre à précision arbitraire

bcpow Alimente un nombre à précision arbitraire

bcpowmod High précision Modulo la puissance des nombresbcscale Définit le nombre de décimales par défaut pour toutes les fonctions mathématiques bc

bcsqrt La racine carrée de tout nombre de précision

    Solutions de traitement numérique courantes
  • Arrondi (arrondi à l'inférieur))
echo floor(5.1);
//输出:5

echo floor(8.8);
//输出:8
Copier après la connexion
  • Arrondir à un (arrondir au supérieur)
  • echo ceil(5.1);
    //输出:6
    
    echo ceil(8.8);
    //输出:9
    Copier après la connexion
  • Méthode d'arrondi ordinaire

    echo round(5.1);
    //输出:5
    
    echo round(8.8);
    //输出:9
    
    //保留两位小数并且进行四舍五入
    echo round(5.123, 2);
    //输出:5.12
    
    echo round(8.888, 2);
    //输出:8.89
    
    //保留两位小数并且不进行四舍五入
    echo substr(round(5.12345, 3), 0, -1);
    //输出:5.12
    
    echo substr(round(8.88888, 3), 0, -1);
    //输出:8.88
    Copier après la connexion
    Méthode d'arrondi du banquier

    Arrondissez à cinq et considérez, s'il n'est pas vide, entrez d'abord, si cinq après cinq sont vides, regardez les nombres impairs et pairs. Si les cinq avant et après sont pairs, ils doivent être écartés. Si les cinq avant et après sont impairs, ils doivent être avancés en un seul.

    Conservez deux décimales, par exemple :

    1,2849 = 1,28 -> Rond

    1,2866 = 1,29 -> Entrez six 1,2851 = 1,29 ->

    1,2850 = 1,28 -> Si les cinq derniers sont vides, regardez impair-pair, si les cinq premiers sont pairs, ils doivent être écartés

    1,2750 = 1,28 -> , si les cinq premiers sont impairs, ajoutez-en un

    Le code d'implémentation est le suivant :

    echo round(1.2849, 2, PHP_ROUND_HALF_EVEN);
    //输出:1.28
    
    echo round(1.2866, 2, PHP_ROUND_HALF_EVEN);
    //输出:1.29
    
    echo round(1.2851, 2, PHP_ROUND_HALF_EVEN);
    //输出:1.29
    
    echo round(1.2850, 2, PHP_ROUND_HALF_EVEN);
    //输出:1.28
    
    echo round(1.2750, 2, PHP_ROUND_HALF_EVEN);
    //输出:1.28
    Copier après la connexion

    Mise à jour Pour les instructions multi-tours, veuillez consulter le manuel officiel :

    http://php.net/manual/zh/function .round.php
    • Mise en forme numérique (milliers de groupes)
    • S'applique à l'affichage des montants, comme On regarde souvent le solde de la carte bancaire.
    • echo number_format('10000.98', 2, '.', ',');
      //输出:10,000.98
      
      echo number_format('340888999', 2, '.', ',');
      //输出:340,888,999.00
      Copier après la connexion
    • Extension

    Champ à virgule flottante MySQL

    Dans MySQL, il existe également un type à virgule flottante lors de la création de champs de table.

    Les types de nombres à virgule flottante incluent les nombres à virgule flottante simple précision (float) et les nombres à virgule flottante double précision (double).

    De même, il n'est pas recommandé d'utiliser le type de nombre à virgule flottante ! ! !

    Il y a des erreurs dans les nombres à virgule flottante Lorsque nous utilisons des données sensibles à la précision, nous devons utiliser des nombres à virgule fixe (décimaux) pour le stockage.

    Résumé

    Grâce à la question de la précision des nombres à virgule flottante, nous avons appris que les décimales des nombres à virgule flottante sont représentées en binaire.

    partagé l'utilisation des fonctions mathématiques de précision arbitraire PHP pour effectuer des opérations de haute précision.

    Partage également des solutions de traitement numérique communes, telles que l'arrondi, l'arrondi, l'arrondi bancaire, le formatage numérique, etc.

    Enfin, pensons au float de MySQL en passant par le float de PHP.

    À l'avenir, lorsque vous utiliserez des calculs en virgule flottante, vous devrez être prudent, les détails déterminent le succès ou l'échec.

    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!

  • Étiquettes associées:
    php
    source:php.cn
    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
    À propos de nous Clause de non-responsabilité Sitemap
    Site Web PHP chinois:Formation PHP en ligne sur le bien-être public,Aidez les apprenants PHP à grandir rapidement!