Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.

Forum Casio - Vos tutoriels et astuces


Index du Forum » Vos tutoriels et astuces » Gérer et éviter les Erreurs Math d'une fonction
Thebigbadboy Hors ligne Membre Points: 246 Défis: 12 Message

Gérer et éviter les Erreurs Math d'une fonction

Posté le 13/09/2021 00:22

Mon tout premier "tuto" !

Vous en avez marre que la calculatrice renvoie à tout bout de champ une Erreur Math en Basic Casio, que ce soit une division par 0 ou un dépassement arithmétique ? Alors lisez ce qui suit !



Il est en effet possible de s'affranchir de ces erreurs, et pour cela un peu de programmation pré-traitement est nécessaire. Finis les programmes qui s'arrêtent sans prévenir !

Par souci de compréhension, la lettre Y fera référence à toute fonction pour laquelle on ne voudrait plus avoir de message d'erreur.

À ce jour, je connais 3 fonctions Basic Casio gérant les Erreurs Math sans nous déranger (et oui, j'allais quand même pas partir de rien ) - et pour lesquelles il serait possible de déduire en quels points Y ne pose pas problème :
  • Les fonctions du menu Sketch, traçant les graphiques
  • La fonction SolveN()
  • Les fonctions de récurrence

Je ne continuerai ce tutoriel qu'avec les fonctions de récurrence, étant la solution la plus rapide, viable, efficace, et de loin. Par contre, cela nous contraint en une chose : il est absolument nécessaire d'utiliser les chaînes de caractères (Strings) - vu depuis le temps qu'elles existent sur Casio il ne devrait pas y avoir de problème .


Ça peut sûrement vous surprendre, mais il existe dans les fonctions de récurrence un moyen d'entrer une fonction tout à fait normale, ne contenant pas d'appel à ses précédantes valeurs... Non seulement je pense que le tutoriel est plutôt intéressant, mais peut-être la récurrence est trop peu connue par les utilisateurs Casio ?

Dans ce tutoriel-ci, je montrerai seulement comment éviter les erreurs de dépassement arithmétique (≥1ᴇ100). Une fois cette méthode comprise, il est plutôt facile de la modifier un peu afin de gérer les éventuelles divisions par 0 .


Bon j'en ai marre de parler, donc essayez d'avaler ça pour voir
anType
0→R Start
209→R End
R SelOn an

//Y étant stockée dans la première chaîne de caractères, et supposant que l'abscisse de Y est la variable X

StrLen(Str 1)→A
StrSrc(Str1,"X"
While Ans
StrLeft(Str 1, Ans-1) + "(S^n)" + StrRight(Str 1, A-Ans→Str 1
A+4→A
StrSrc(Str1,"X"
WhileEnd
Str 1→an

3→S
DispR-Tbl
R Result
Dim Mat Ans
S^Mat Ans[List Ans[1],1 //Ans est maintenant l'abscisse maximale pouvant être donnée à Y

Les "n" présents dans ce code sont des caractères spéciaux ! Sélectionnez bien "n(RECUR)" dans votre catalogue de fonctions ([SHIFT]+[4]) ! Ce serait bête de se tromper, surtout qu'il y a 4 différents "n" en Basic Casio....


Un peu trop brut ? Bon d'accord je veux bien expliquer tout ce que nous avons là


- Tout d'abord, il faut savoir que les fonctions de récurrence calculent tout d'une traite, et les résultats peuvent être enregistrés dans une matrice. Il est donc obligatoire de fixer les bornes au préalable. La fonction de récurrence que nous allons construire se trouvera dans an, mais peut aussi se trouver dans bn ou encore cn. À noter que R Start et R End sont des caractères spéciaux, malgré l'espace qu'ils contiennent chacun. R SelOn an est quant à lui composé de 2 caractères spéciaux : "R SelOn " et an. Je vous recommande franchement de désélectionner bn et cn si ce n'est déjà fait (R SelOff ), et par la même occasion de désactiver la somme des éléments (ΣdispOff). Le poids utilisé par les récurrences monte très vite, et le code ci-dessus utilise déjà 10 ko, 5 ko dans l'application "RECUR" et 5 ko - ou moins, en fonction de si Y a un dépassement arithmétique ou non - dans Mat Ans.
La phase "d'initialisation" est terminée


- Malheureusement, les fonctions de récurrence renvoient une Erreur Syntaxe si on fait un appel à une fonction graphique (par ex "Y1(n)"). On doit donc changer tous ces X par la variable n. Lors du calcul des images d'une onction de récurrence, il faut aussi savoir que le pas des abscisses (n) est fixe, et vaut 1. Imaginez le nombre d'entrées dans un tableau nécessaires pour arriver à l'abscisse 9ᴇ99 ! Tout simplement impossible.
De plus, vu qu'on aimerait avoir l'abscisse maximale avant que Y ne donne d'erreur de dépassement arithmétique, il serait judicieux d'avoir une plus grande précision pour des petites abscisses que pour les grandes (10^X donne une erreur à partir de 100, ce serait mieux dans un cas comme celui-ci de s'en rapprocher le plus).
Voilà pourquoi une progression exponentielle est intéressante ! La base choisie est arbitraire, et dépend aussi de la borne supérieure R End.

Je ne m'attarde pas plus sur le code pour remplacer les "X" par des "(S ^ n)".
Une seule chose à noter ici : ce remplacement pourrait changer l'ordre des opérations de Y ! Ajoutez donc bien des parenthèses dès qu'il y a ambiguïté ! C'est un cas assez spécifique, mais ça l'est si Y possède une multiplication sans opérateur explicite. Par exemple "Int 10X" - 10X sera d'abord calculé, et ensuite Int - donnera "Int 10(S ^ n)", et cette fois-ci la calto verra ce calcul comme suit : "(Int 10) * (S ^ n)". Autant dire que ce n'est pas exactement ce que vous vouliez... Comme quoi des parenthèses peuvent sauver la mise


- DispR-Tbl va calculer absolument tous les points. N'hésitez pas à ajouter un Disp juste après cette instruction (◢), et vous verrez une matrice pouvant contenir des éléments "ERROR" dedans. Voilà donc l'utilité de la prochaine instruction : R Result. Elle transforme le précédant tableau en matrice en enlevant tous les éléments "ERROR". S'il n'y a que des "ERROR" dans ce tableau, la matrice ne pourra être créée et une Erreur Dimension sera renvoyée.
Il ne nous reste plus qu'à obtenir l'abscisse maximale que la fonction de récurrence a réussi à passer, et vous obtenez maintenant un seuil à ne pas dépasser lors de votre étude de fonction - ou que sais-je .


Une précision d'un facteur 3 peut vous paraître trop grande - et à moi aussi - , j'ai donc essayé de pousser le bouchon à la précision maximale que je pouvais avoir : une base 1.26 avec une borne supérieure R End valant 996 (une Erreur Plage serait renvoyée si R End ≥ 1000). Mais 38 ko libres n'ont pas l'air de suffire
Pour ceci je vous conseillerais donc (si vous voulez être plus précis) de redéfinir les bornes et de réitiérer grâce à la dernière abscisse maximale acceptée.
Comme vous l'aurez compris, cette méthode sert à éviter les Erreurs Math, mais peut passer par dessus une erreur ponctuelle sans s'en rendre compte - comme une division par 0.


Certains points de ce tutoriel peuvent être bien évidemment superflus - tout comme des fonctions Basic Casio - et par conséquent n'hésitez vraiment pas à poser des questions, ou même écrire vos commentaires

En espérant que tout ceci est pu au moins être intelligible, merci de votre lecture !


Lephenixnoir En ligne Administrateur Points: 20989 Défis: 143 Message

Citer : Posté le 13/09/2021 07:11 | #


Voilà des techniques nouvelles tout à fait subtiles !

Est-ce qu'on ne peut pas en enrober ça dans un sous-programme qui testerait exactement une abscisse et renvoie la valeur du calcul si elle existe et une erreur dans une autre variable sinon ? Ce serait lent mais ce serait un moyen efficace de se protéger.
Thebigbadboy Hors ligne Membre Points: 246 Défis: 12 Message

Citer : Posté le 13/09/2021 10:52 | #


Oui en effet ce serait possible

Désolé pour le gros côté brouillon de ce "tuto"

Mais alors il vient un problème à régler : si toutes les abscisses testées renvoient une erreur (avec la fonction de récurrence), la fonction R Result renverra une Erreur dimension. Il faut donc au moins un point appartenant au domaine de la fonction, le tout serait de savoir comment le prendre.
Une idée serait - par exemple si on veut calculer l'image de P - de balayer quelques abscisses entre P-1E6 et P+1E6 ?

Malheureusement le problème d'arrêt du programme par une erreur n'est pas tout à fait réglé
Un problème sans solution est un problème mal posé — Albert Einstein

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v42 © créé par Neuronix et Muelsaco 2004 - 2021 | Il y a 80 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd