Précision de stockage d'une variable différente de celle de comparaison
Posté le 14/03/2021 20:44
Alors voilà, ça peut paraître un peu "bizarre", mais récemment en travaillant sur mon programme
Number to Fraction, j'ai découvert que la précision de la calculatrice est différent suivant les manipulation qu'on fait avec les nombres/variables.
Comme vous le savez sûrement, toute variable peut contenir un nombre jusqu'à 15 chiffres
significatifs (comme par ex √5).
Posons A = 987 654 987 654,333 et B = 987 654 987 654,25 (la place des virgules n'a pas d'importance). Je pensais donc naturellement que A = B renverrait faux, mais en réalité ceci renvoie vrai.
En effet lorsqu'on compare 2 valeurs, seulement les 13 premiers chiffres significatifs comptent. Je voulais donc savoir pourquoi ce choix et aussi si possible expliquer les prochains cas. Il aurait fallu, pour que la calto renvoie faux, que B est comme partie décimale 0,233.
Pour continuer sur l'exemple,
- Frac A = Frac B renvoie vrai (comme attendu)
- Frac (3A) renvoie 0 (bizarrement pas 0,999)
Je n'ai pas vraiment essayer d'autres choses, donc peut-être manque-t-il des cas intéressants ?
En tout cas, dans une certain sens, je peux comprendre pourquoi ce choix (limiter à 13 chiffres sign. la comparaison) : éviter les erreurs d'arrondi / de calculs. Mais ce qui est embêtant, c'est que pour tester si 2 valeurs sont
exactement identiques il va falloir ruser (et surtout écrire un code bien plus lourd qu'un simple "=").
Citer : Posté le 14/03/2021 21:13 | #
À vue de nez, c'est parce que 987 654 987 654,25 = 987 654 987 654,3 avec 13 CS. En effet, 0,25 est arrondi à 0,3, tout comme 0,333 est arrondi à 0,3.
Pour Frac, même comportement : 3A = 2 962 964 962 962,999 donc si on prend 13 CS, on obtient 2 962 964 962 962. Et Frac(2 962 964 962 962) = 0.
Rien de bien aberrant en gros
En fait, ce ne sera pas possible. Comment tu peux (même en rusant) savoir si A → 1.414 213 562 373 est égal à sqrt(2) ou au nombre décimal 1.414 213 562 373 ?
Citer : Posté le 14/03/2021 21:13 | #
Je pense qu'il s'agit d'un problème d'annulation (cancellation ou loss of significance) combiné à une heuristique du moteur de calcul. Après quelques tests, j'ai remarqué dans RUN/MAT que :
→ 0.103
987654987654.333 - 987654987654.24
→ 0
La différence entre les deux est la perte d'un chiffre significatif. Le résultat correct du second calcul est 0.93. Le résultat commence donc par 13 zéros, et mon intuition c'est que le moteur de calcul arrondit volontairement les résultats intermédiaires à 13 chiffres pour limiter les dégâts causés par les approximations de calcul. Le but étant que si tu pars de valeurs exactes, à chaque opération les erreurs plus faibles que 10⁻¹³ sont gommées. Et du coup à la fin, tu as un résultat qui reste exact plus longtemps (et sur lequel tu peux faire une comparaison de flottants même si en principe c'est impossible).
En tous cas, le fait que ça apparaisse sur la soustraction (et sur l'addition, en remplaçant A-B par A+(-)B) montre que ce n'est pas une question de comparaisons mais bien de résultats intermédiaires. Sur la comparaison tu le vois simplement parce que A=B c'est calculé par A-B=0.
Citer : Posté le 14/03/2021 21:47 | #
En fait, ce ne sera pas possible. Comment tu peux (même en rusant) savoir si A → 1.414 213 562 373 est égal à sqrt(2) ou au nombre décimal 1.414 213 562 373 ?
Si, c'est possible, même si redondant. Par exemple cette condition-ci renverra 0 (car √2 = 1.414 213 562 373 1 sur la calto) :
Bien évidemment cela n'est valide que si l'on ne considère pas les erreurs de calculs (ce que je fais volontiers ). Cela permait d'outrepasser le problème des 13 CS, il faut juste que le résultat de 10A soit dans l'intervalle [10, 100[ (on va limiter aussi l'intervalle par le haut car un nombre peut très bien avoir 15 CS sans partie décimale ).
Merci pour vos clarifications
Citer : Posté le 14/03/2021 21:49 | #
Ce que Darks voulait dire c'est que √2 n'est pas un nombre décimal, donc dès que tu as une variable elle n'est jamais égale à √2. Et là tu arrives sur le problème fondamental que l'égalité stricte entre tes nombres est une illusion parce que les nombres eux-mêmes sont une illusion. À chacun de tes topics je suis toujours persuadé que ça va finir par te poser des problèmes... ^^"
Citer : Posté le 14/03/2021 21:56 | #
On va faire plus explicite :
For 1->A To 2
List 1[A]→V
If // Code qui vérifie si V est rationnel
"Rat"
Else
"Irrat"
IfEnd
Next
Je te mets au défi de faire un code qui répondra "Rat, Irrat" dans se baser sur la valeur de A (ce serait tricher).
Citer : Posté le 14/03/2021 21:58 | #
C'est le sujet de son topic précédent btw.
Citer : Posté le 14/03/2021 22:18 | #
Ah d'accord je vois, je me fais toujours avoir
En même temps, dès qu'on travaille numériquement la délimitation entre les nombres irrationnels des décimaux finis est un peu "complexe"...
Par exemple, exécutons "√2→A". Si on entre dans une nouvelle ligne "A" et en jouant avec F↔D on peut voir que la calto affiche aussi bien √2 que 1.414....... Écrivons manuellement tous les chiffres de √2 et enregistrons-les dans une autre variable : "1.4142135623731→B". Maintenant ce que je ne comprends pas, c'est qu'il est impossible à partir de B d'afficher "√2" alors B devrait contenir exactement les mêmes informations que A . Personnellement, je ne vois que 2 solutions : soit le stockage des variables ne s'arrête pas à 15 CS, soit la calto a retenu quelque part que A pouvait être affiché comme un nombre irrationnel. J'ai un doute sur les 2 mais c'est tout ce que je vois, et je ne comprends pas pourquoi ces différences entre A et B .
Citer : Posté le 14/03/2021 22:22 | #
La séparation entre les deux n'est pas complexe quand on y réfléchit : tous les nombres sont rationnels.
C'est parce que tu le tapes dans RUN/MAT. Si tu tapes √2→A dans un programme, afficher A dans RUN/MAT ne te donne pas la forme exacte.
RUN/MAT utilise un format différent du reste, et fait du calcul symbolique avec les rationnels, les multiples de π et les racines (Critor appelle ça "ℚ-π-Rac"), c'est pour ça qu'il peut t'afficher cette chose. Mais PRGM non, de mémoire PRGM sait utiliser quelques fractions mais seulement si tu les saisis à la main avec ⌟ (la touche fraction).
Il n'y a pas de miracle malheureusement, si RUN/MAT sait que c'est une racine c'est parce que RUN/MAT s'est souvenu tout le long du début à la fin que c'en est une. Il n'y a pas d'autre façon de s'en sortir.
Citer : Posté le 14/03/2021 22:28 | #
Ok, j'avais même essayé d'effacer tous les calculs dans RUN/MAT, sans aucun changement pour A.
J'ai donc essayer comme tu l'as fait remarqué : en exécutant √2→A dans PRGM, puis en affichant A dans RUN/MAT, on ne sait pas obtenir la "forme irrationnelle".
Ben voilà, merci ! Vous m'avez bien aidé et je ne pense plus avoir de question (pour ce topic-ci ). Je reviendrai à la charge pour la recherche de condition d'existence de l'exponentielle A^B
Citer : Posté le 14/03/2021 22:31 | #
Essaie de réfléchir à la question suivante : d'après les observations, A^B (A < 0) renvoie un résultat si et seulement si B a une forme rationnelle dans RUN/MAT, quand saisi à la main (teste 1÷3-ᴇ-4 et 1÷3-ᴇ-5). Vois si tu peux avoir un moyen de déterminer ça dans PRGM (je ne sais pas si c'est le cas mais peut-être qu'une fonction obscure existe pour le faire !).
Pense bien que ce n'est pas un problème mathématique, c'est bien un problème de « que fait le code de l'opération A^B au juste ? ».