Discuss Scratch

Harryscratch51
New Scratcher
2 posts

Problème avec la double précision

Bonjour !

Une idée de prof de maths : j'ai créé un programme qui propose un nombre à l'élève, et l'élève doit le diviser par 10.

Par exemple, si je propose 29.37, l'élève doit répondre 2.937.

Mais, là, gros problème ! Si l'élève dit 2.937, une fois sur deux ou trois, Scratch va répondre : Faux, la réponse est 2.9370000000000004 ou Faux, la réponse est 2.936999999999996.

Je comprends qu'il y ait des problèmes d'arrondi sur un cosinus, mais sur une division par 10 !!!!????

A noter que, quand quand je fais afficher la variable qui calcule 29.37/10, elle affiche normalement 2.937.

Bien sûr, je pourrais tester si Abs(réponse élève - réponse scratch) < 10^-10, mais si l'élève a donné une réponse carrément fausse (par exemple 293.7), impossible de le corriger en lui donnant la bonne réponse puisque Scratch va afficher 2.9370000000000004

Quelqu'un a une idée pour corriger (ou contourner) le problème ?
TechnoFR
Scratcher
23 posts

Problème avec la double précision

Tu as raison moi aussi ça fait ça.
smrman
Scratcher
1000+ posts

Problème avec la double précision

Bonjour Harryscratch51,

J'ai peut-être la réponse pour ton problème.

Rends-toi la vie simple.

Crée 2 variable:
(nombre)
(nombre divisé)

puis quelques scripts vraiment simple::
quand le drapeau vert pressé
répéter indéfiniment
[nombre v] prend la valeur (nombre aléatoire entre (0.00) et (100.00))
[nombre divisé v] prend la valeur ((nombre) / (10))
répéter jusqu’à <(réponse) = (nombre divisé)>
dire (regroupe (nombre) [ divisé par 10])
demander [] et attendre
end
end

Last edited by smrman (May 21, 2016 20:22:34)

lederniersamourai
Scratcher
500+ posts

Problème avec la double précision

Je suppose que les calculs proposés ne sont pas trop complexes.
On peut donc supposer que le degré de précision que donne scratch pour effectuer les calculs est bonne (sauf s'il reste des bugs dans scratch).

Le problème se réduit donc à choisir un représenant unique de classes d'équivalences. Classes d'équivalences car il y a plusieurs représentations “électroniques” en bits et/ou symbolique par l'affichage en décimal avec trop de décimales.

Pour choisir obtenir le bon représentant de la classe d'équivalence, on pourrait utiliser “round” (arrondir) à chaque étape intermédiaire et avant l'affichage.
Dans ce cas, (1.0/7.0)*7.0 donnera 1 et sera codé round(round(round(1.0)/round(7.0))*round(7.0))
Il y a certainement des “round” inutiles, mais cela permet de ne pas trop réfléchir à ce qu'il faut faire et surtout d'être systématique.

Bien entendu cela ne fonctionne que si les calculs n'exigent pas une précision trop grande pour trouver la bonne solution.
Harryscratch51
New Scratcher
2 posts

Problème avec la double précision

Mmmmh… Merci pour les propositions, Smrman et Le dernier samouraï…

Apparemment, le “arrondi” permet de camoufler le problème…

Première remarque :
"Si réponse = nombre/10" ne passe pas car nombre/10 calculé “à la volée” donne un nombre en double précision avec des chiffres indésirables en 16ème position, pour une raison qui persiste à m'échapper…

Deuxième remarque en introduisant une variable auxiliaire :
"Mettre solution à nombre/10
Si réponse = solution" ne passe pas non plus… Même chose que pour la première remarque.

Troisième remarque en utilisant les arrondis :
"Mettre solution à nombre/10
Mettre solution à arrondi(solution*100) / 100
Si réponse = solution"
a l'air de fonctionner et de produire un nombre avec deux décimales et pas 16.

Quatrième remarque :
"Mettre solution à nombre/10
Dire solution pendant 2 secondes“ affiche un nombre à 1 décimale (même s'il en a 3 ou 16)

tandis que

”Mettre solution à nombre/10
Dire (Regroupe “La réponse est” solution) pendant 2 secondes" affiche un nombre avec toutes les décimales…

Il y a décidément des raisonnements de Scratch qui me semblent défier toute logique…

Last edited by Harryscratch51 (May 22, 2016 11:04:46)

samuelrozenman
Scratcher
38 posts

Problème avec la double précision

J ai entendu sur un forum parler de problème de virgule flottante. J en sais pas plus il faut peut-être regarder sur internet. Moi aussi ça m embête car j essaye de créer un programme avec les fréquences d'un lancé de dé et évidemment elles sont fausses
lois-marquez
Scratcher
1 post

Problème avec la double précision

moi, pour créer ma calculatrice ( sur scratch ) j'ai aussi ce problème, quand on entre un nombre à virgule, il y a souvent des bugs, je vous laisse aller tester : https://scratch.mit.edu/projects/126711369/
michel40
New Scratcher
1 post

Problème avec la double précision

Bonjour,

je relance ce vieux post car c'est un problème récurrent avec les nombres décimaux, problème que l'on retrouve dans les autres langages de programmation.

Les nombres sont codés en base 2 en informatiques et beaucoup de nombres décimaux (nombres ayant une écriture exacte en base 10) ont un développement illimité en base 2.
Par exemple 1/10, n'a pas d'écriture exacte en base 2 donc une division par 2 sera effectuée en multipliant par une valeur approchée de 1/10 d'où les résultats approchés et non exacts que vous trouvez.
bidulule
Scratcher
1000+ posts

Problème avec la double précision

michel40 wrote:

Bonjour,

je relance ce vieux post car c'est un problème récurrent avec les nombres décimaux, problème que l'on retrouve dans les autres langages de programmation.

Les nombres sont codés en base 2 en informatiques et beaucoup de nombres décimaux (nombres ayant une écriture exacte en base 10) ont un développement illimité en base 2.
Par exemple 1/10, n'a pas d'écriture exacte en base 2 donc une division par 2 sera effectuée en multipliant par une valeur approchée de 1/10 d'où les résultats approchés et non exacts que vous trouvez.
merci michel
Itharius
Scratcher
1000+ posts

Problème avec la double précision

Une solution claire n'a pas été donnée à ce problème dans ce topic et ça me gêne parce que des personnes qui ferait une recherche sur internet via google comme l'a surement fait michel40 n'auront pas une réponse claire à leur problème, relatif à l'approximation des flottants dû au stockage des nombres en binaire.

Voici donc le lien de la discussion que nous avons déjà eue sur ce forum concernant ce problème avec toutes les explications détaillées nécéssaires faites entre autres par Sbissay et Deuzz
https://scratch.mit.edu/discuss/topic/247189/?page=1

Et pour résumer si vous n'avez pas envie de lire cette discussion (ce qui serait vraiment un tord):

Ne jamais tester une égalité avec des nombres à virgule

ce que malheureusement Harryscratch51 tentait de faire en comparant certainement la réponse à la variable de son chiffre à virgule divisé par 10.

La solution pour son cas, aurait été de rajouter dans son programme un test pour savoir si le premier chiffre choisit était ou non à virgule. et si c'était le cas , de multiplier d'autant qu'il aurait diviser par la suite son chiffre pour le rendre Entier.
Donc au lieu de stocker 29.37/10 dans une variable pour la comparer à la réponse d'un demander et attendre ( ce qui conduira à dire que 2.937 est faux), il aurait du stocker (29.37x100)/(10x100).

Powered by DjangoBB