erreur de calcul

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : erreur de calcul

Re: erreur de calcul

par devlop78 » 18 déc. 2010, 20:19

boucle de ceinturion PéHashPépurien ?

Re: erreur de calcul

par hakazizi » 18 déc. 2010, 20:16

Je sais pas ce qu'ils fument chez php mais ils faudraient qu'ils arrêtent de jouer à la roulette russe avec les bits ^^
Sa vol pas haut même en dessous de la boucle :-*

Re: erreur de calcul

par dunbar » 18 déc. 2010, 16:06

Je suis tombé sur cette erreur de calcul par PHP :

Code : Tout sélectionner

<?php $a = 0.7; $b = 7; $c = $a * $b; $d = 4.9; print $d - $c; ?>
et le résultat (qui devrait être 0 pour ceux qui n'auraient pas suivi)
8.881784197E-16

étonnant non ?
Quelqu'un pourrait-il m'expliquer cela ?
Avec number_format cela fo :? nctionne nickel

Re: erreur de calcul

par Mazarini » 15 déc. 2010, 10:22

Bonjour,

C'est un problème vieux comme l'informatique. Le fait de de ne pas tester X = 0 mais X < pas grand chose (pas grand chose étant fonction de la précision souhaitée) faisait partie du premier cours pour le Fortran.

Dans la mesure du possible, je fais mes calculs en centime pour ne travailler qu'avec des entiers.

Re: erreur de calcul

par epommate2 » 14 déc. 2010, 11:57

La seule chose qui ne marche pas c'est de tester l'égalité de deux flottants : l'opération devrait être interdite !
echo (0.49 == 0.7*0.7)?"égale":"pas égale";
echo "\n";
echo (bccomp(0.49,bcmul(0.7,0.7))==0)?"égale":"pas égale";
echo "\n";

Re: erreur de calcul

par devlop78 » 14 déc. 2010, 11:03

Il est clair que l'opération de base tel que le calcul pour un ordinateur, est déroutant à ce niveau là. Si quelqu'un a le temps d'essayer de tester la même chose sur un autre langage de programmation, ce serait avec joie ; On pourrait en conclure, comme le dit l'article sur les nombres floattant php, qu'une addition n'est pas $x + $y, mais doit passer par une fonction qui se charge de cette "marge" telle que SUM($x,$y).

Re: erreur de calcul

par xTG » 14 déc. 2010, 10:40

J'ai pas eu le temps de tout lire mais il semblerait que je peux jeter mon cours sur la représentation des nombres flottants en binaire...
L'art de nous apprendre des aspects théoriques qui sont entièrement faux, j'adore...

Le pire dans tout ça c'est que j'ai déjà eu à faire des calcul flottants sur un ARM7TDMI et que j'ai jamais trouvé quoi que ce soit qui bug...
Alors que si ce que cet article avance il n'est pas possible d'obtenir un quelconque calcul correct non ? A moins que dans certains cas il soit capable de combler la marge d'erreur ? Ou bien que la calculette que j'utilisais pour vérifier affichait la même marge d'erreur. x)

Re: erreur de calcul

par epommate2 » 14 déc. 2010, 07:42

Mais non, c'est comme ça depuis que le monde est monde et le float flottant !

Je me souviens que c'était déjà le cas en C et fatalement, comme PHP est basé dessus, il utilise le même mode de calcul flottant.
Pour faire simple : la mantisse est écrite en base 2 (et pas 10), donc le nombre est écrit :
x0*2^-1 + x1*2^-2 + ...

et comme tous nombre réel (et c'est le cas de 0.49) ne peux s'écrire de cette manière, il est enregistré en 0.4899999999.

(voici la version longue et complexe de ce que j'avance : http://docs.sun.com/source/806-3568/ncg_goldberg.html )

Re: erreur de calcul

par devlop78 » 14 déc. 2010, 00:57

Ce qui me chiffonne aussi c'est que si 4.9 - $x != 0, c'est que $x != 4.9

Or un echo $x nous affiche pourtant bien 4.9. Il faudrait faire le test avec Java ou JavaScript pour voir ce que ça donne. Bientôt 5 - 5 fera 12.

Re: erreur de calcul

par xTG » 13 déc. 2010, 23:47

Il n'y a pas de raison que 4.9 soit coupé. Il y aurait une infinité de chiffres après la virgule je dis pas mais là...
Le codage d'un nombre à virgule revient à mettre tout derrière la virgule (donc la mantisse) et de garder l'exposant pour revenir au nombre original.

Donc 4.9 se codera 0.49 avec un exposant de 1.
La mantisse acceuillera le chiffre 49 (ce qui se code aisément sur 23bits...) et l'exposant prendra un bit sur huit donc...

Question de codage du chiffre il n'y a pas de raison d'avoir de moins bons résultat avec PHP qu'avec la calculatrice, les deux sont codés sur 32bits.

Re: erreur de calcul

par devlop78 » 13 déc. 2010, 21:16

Hmmm ... Je crois avoir compris. Cela est dû à la restriction de la quantité de bits dans la représentation du nombre. Si par exemple, 4,9 s'écrit 10000111100000001 en binaire (c'est du gros pif), mais qu'il est limité en taille, il sera donc arrondi ou coupé, ce qui ne donnera pas 4,9.
* le signe est représenté par un seul bit, le bit de poids fort (celui le plus à gauche)
* l'exposant est codé sur les 8 bits consécutifs au signe
* la mantisse (les bits situés après la virgule) sur les 23 bits restants
Bref, pour une opération arithmétique, mieux vaut utiliser sa calculatrice ^^

Re: erreur de calcul

par epommate2 » 13 déc. 2010, 07:03

0.7 * 7 = 0.4899999999

0.49 - 0.4899999999 = epsilon

Le compte est bon !

Si tu veux savoir si la soustraction de deux flottants donne 0, il faut faire :
$x - $y < $epsilon

mais jamais
$x - $y == 0

Tous est dans la doc : http://php.net/manual/fr/language.types.float.php

Re: erreur de calcul

par devlop78 » 13 déc. 2010, 01:43

Par contre 0.5 et 10, ça marche.

Re: erreur de calcul

par devlop78 » 13 déc. 2010, 01:42

Oui. Et si on fait echo $c, ça affiche bien le truc. Il n'y a qu'une seule décimale, :shock:

Re: erreur de calcul

par stealth35 » 13 déc. 2010, 01:30

mais c'est bizarre quand même par que si on remplace $c par 4.9 ca marche...