Bonjour,
simplifier(11.98*x-12*x)
renvoie : -0.0200000000004*x
Joyeuses fêtes.
Problème de simplification
Modérateur : xcasadmin
Re: Problème de simplification
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)".
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
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:
En y réfléchissant je me demande s'il ne serait pas possible (dites moi si je me trompe) de proposer ce script:
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.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)
Re: Problème de simplification
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 ...
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
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
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
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.