Maison  >  Article  >  développement back-end  >  Les opérations en virgule flottante en PHP sont-elles exactes ?

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

青灯夜游
青灯夜游original
2023-01-04 20:50:243531parcourir

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

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
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
  • Arrondir à un (arrondir au supérieur)
  • echo ceil(5.1);
    //输出:6
    
    echo ceil(8.8);
    //输出:9
  • 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
    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

    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
    • 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!

  • 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