Page 1 sur 1

Problème de simplification

Publié : mar. déc. 27, 2011 11:07 am
par dlefur
Bonjour,

simplifier(11.98*x-12*x)

renvoie : -0.0200000000004*x

Joyeuses fêtes.

Re: Problème de simplification

Publié : mar. déc. 27, 2011 1:55 pm
par Alek
Ce serait plutôt un problème d'arithmétique: 11.98-12 renvoie -0.0200000000004 (le "vrai" résultat serait -0.02000000000044; on peut le voir si on change Digits après l'opération)

C'est le mystère de floats (discuté par ailleurs ici), mais pas sur si c'est un bug. L'ordinateur fait le calcul en base 2, la conversion en base 10 introduit (presque) toujours une erreur d'arrondi ; ce qui est 'exact' en base 10 ne l'est plus en base 2.

En fait, je pense que le résultat affiché est 'correct', c-a-d c'est ce qu'on obtient réellement avec la machine. Sous un autre système ça pourrait être 0.02, c'est le cas de xcas sous windows; et par exemple l'interpréteur de python affiche 11.98-12 = -0.019999999999999574.

Afficher 0.02 est intuitif car nous faisons tacitement un calcul mental exact avec des rationnels. Mais avec les floats de la machine ce serait un peu trompeur, surtout si on voulait par exemple stocker cette valeur dans une variable et la réutiliser pour d'autres calculs.

Une solution pourrait éventuellement consister à tronquer l'affichage d'une manière "plus-que-évidente" à, par exemple, 4 chiffres après la virgule et, au cas où, pouvoir accéder à la "vraie" valeur avec une commande "montre-tout(x)".

Re: Problème de simplification

Publié : mar. déc. 27, 2011 6:30 pm
par alb
Je suis toujours désemparé pour répondre quelque chose de simple à des élèves.
En y réfléchissant je me demande s'il ne serait pas possible (dites moi si je me trompe) de proposer ce script:
DIGITS:=3
A:=0.05
B:=0.0625
u(k):={DIGITS:=k;string(A*20-1)}
v(k):={DIGITS:=k;string(B*16-1)}
seq([k,u(k)],k,1,20)
seq([k,v(k)],k,1,20)
Ensuite leur demander de modifier (en les guidant) les valeurs de A et B et d'essayer de leur faire deviner quels sont les "décimaux" qui renvoient dans la liste toujours des 0.

Re: Problème de simplification

Publié : mer. déc. 28, 2011 9:43 pm
par Alek
Le problème c'est que cela peut dépendre de la machine/système/compilateur C/bibliothèque de calcul...
En plus, si je comprends bien, xcas change radicalement son l'algorithme si Digits dépasse 13.
Cela peut eventuellement influencer aussi la présentation de résultats (exemples dans l'autre discussion).

Avec ce code, j'obtiens des résultats différents sous windows et linux. Sous windows les deux valeurs me donne toujours 0.
Sous linux seulement B a cette propriété.
Je ne vois donc pas trop ...

Re: Problème de simplification

Publié : jeu. déc. 29, 2011 7:44 am
par alb
Effectivement
Digits:=k avec k entre 1 et 13
evalf(3*0.1-0.3)
evalf(8*0.125-1)
donne selon l'OS des résultats distincts pour 3*0.1-0.3

Re: Problème de simplification

Publié : jeu. déc. 29, 2011 8:15 am
par parisse
C'est la presence du flag de compilation -DDOUBLEVAL qui change la donne, s'il est present les double sont stockes integralement (53 bits de mantisse), sinon 8 bits sont tronques. Il semble que sous windows je compile avec -DDOUBLEVAL.