Forum Programmation.php bug dans php, nombre mal tronqué

Posté par  (site web personnel) .
Étiquettes : aucune
0
24
oct.
2005
Dans un script je génère un nombre aléatoire :
l'utilisateur entre deux valeur a et b
que je compare avec le nombre généré par le script.

Le but étant d'écrire le nombre $nombre_alea sous la forme $a .10^$b
Le script génère une réponse pour comparaison qui sera $p . 10^$puissance

A et p doivent donc être au finale égaux !
Mais il se trouve que php trouve régulièrement une différence de l'ordre de 1E-15.

problème : est ce un bug ? comment le résoudre ?


PS : la page exécutant le code est là :
http://kobold.myftp.org/math/ecriture_science.php
le code est là :
http://kobold.myftp.org/math/ecriture_science.txt
ci-dessous un extrait du code



// initialise avec les microsecondes depuis la dernière seconde entière
mt_srand((float) microtime()*1000000);

$randvala = mt_rand(-30000,30000);
$randvalb = mt_rand(-9,9);
$div = pow(10,$randvalb);
$nombre_alea = $randvala / $div ;


$nombre = abs ($nombre_alea) ;
$puissance = floor (log10($nombre) ) ;
$p = ($nombre_alea / pow(10,$puissance) ) ;

//test débuggage

" TEST de débuggage SOLUTION ALGO : $p x 10 $puissance " ;
"p : $p" ;
"a : $a" ;
$dif = $p-$a ;
echo "p-a : $dif " ;
  • # juste une idée

    Posté par  . Évalué à 1.

    Je connais pas très bien les capacités de calcul de php mais une erreur de 1e-15, ça ressemble pas mal à l'approximation que tu obtiendra avec pas mal de langages quand tu fait des calculs en virgule flottante et que tes nombres sont définis comme doubles.
    • [^] # Re: juste une idée

      Posté par  (site web personnel) . Évalué à 1.

      oui, mais vu que je tronque le nombre ( la fonction floor me permet de ne prendre que la partie entière.)

      et que je ne fais qu'une division dans la foulée, mais une division par un rationnel : 10^x

      je ne comprend pas le reliquat de 1E-15
      je ne comprend pas cette erreur de précision.

      D'autant plus que de temps en temps l'égalité est correcte. (au jugée, je dirais une fois sur 4)
  • # vive les nombres flottants

    Posté par  . Évalué à 2.

    comme expliqué dans : http://www.nexen.net/docs/php/annotee/warn.float-precision.p(...)
    tu devrais utiliser la bibliothèque GMP (si tu le peux...)

    il faut savoir par exemple que multiplier par 10 et diviser par 0.1 ne donnent pas le même résultat.

    Si dans ton cas $randvalb vaut -1, tu vas diviser par $div qui vaudra presque 0.1 mais pas exactement car ce nombre a un nombre infini de chiffres après la virgule en base 2. Donc au final tu vas multiplier par un ***flottant*** qui vaut ***presque*** 10 alors que tu aurais pu multiplier par un ***entier*** qui vaut ***exactement*** 10.

    Donc à part pouvoir utiliser une bibliothèque de calcul exact type BC ou GMP (c'est pour ça qu'elles utilisent des chaînes de caractères comme représentation des nombres), tu retrouveras toujours ces problèmes inhérent à la représentation des nombres.
    • [^] # Re: vive les nombres flottants

      Posté par  (site web personnel) . Évalué à 1.

      ok merci pour l'explication qui est clair et précise et que je réutiliserais (c'est sous creative common ?) ;)

      maintenant je fais comment pour utiliser GMP ?
      le script et sur mon serveur, je peux installer ce que je veux et modifier ce que je veux.

Suivre le flux des commentaires

Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.