Obligement - L'Amiga au maximum

Vendredi 06 juin 2025 - 12:23  

Translate

En De Nl Nl
Es Pt It Nl


Rubriques

Actualité (récente)
Actualité (archive)
Comparatifs
Dossiers
Entrevues
Matériel (tests)
Matériel (bidouilles)
Points de vue
En pratique
Programmation
Reportages
Quizz
Tests de jeux
Tests de logiciels
Tests de compilations
Trucs et astuces
Articles divers

Articles in English


Réseaux sociaux

Suivez-nous sur X




Liste des jeux Amiga

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z,
ALL


Trucs et astuces

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Glossaire

0, A, B, C, D, E, F,
G, H, I, J, K, L, M,
N, O, P, Q, R, S, T,
U, V, W, X, Y, Z


Galeries

Menu des galeries

BD d'Amiga Spécial
Caricatures Dudai
Caricatures Jet d'ail
Diagrammes de Jay Miner
Images insolites
Fin de jeux (de A à E)
Fin de Jeux (de F à O)
Fin de jeux (de P à Z)
Galerie de Mike Dafunk
Logos d'Obligement
Pubs pour matériels
Systèmes d'exploitation
Trombinoscope Alchimie 7
Vidéos


Téléchargement

Documents
Jeux
Logiciels
Magazines
Divers


Liens

Associations
Jeux
Logiciels
Matériel
Magazines et médias
Pages personnelles
Réparateurs
Revendeurs
Scène démo
Sites de téléchargement
Divers


Partenaires

Annuaire Amiga

Amedia Computer

Relec


A Propos

A propos d'Obligement

A Propos


Contact

David Brunet

Courriel

 


Programmation : C - Évaluateur de fonctions
(Article écrit par Randy Finch et extrait du Randy Finch's Web Site - octobre 1989)


Voici un article qui décrit un programme C pour évaluer des fonctions 3D définies par l'utilisateur de la forme Z=f(X,Y) en utilisant des valeurs de X et Y sélectionnables par l'utilisateur.

En convertissant un programme de traçage de fonctions 3D de BASIC en C, j'ai réalisé que je devais écrire une routine d'évaluation de fonctions similaire à celle d'un tableur. Pour tracer différentes fonctions dans la version BASIC du programme, il est possible d'arrêter le programme, de modifier la fonction, puis de relancer le programme. Dans un langage compilé comme le C, ce n'est pas possible. J'avais besoin d'une routine C qui accepterait une fonction mathématique comme entrée de chaîne de caractères, puis évaluerait la fonction à différentes valeurs de variables. Après avoir pris connaissance d'un programme Modula-2 démontrant cette technique dans le livre "Software Engineering With Modula-2 And Ada" de Weiner et Sincovec (John Wiley & Sons, Inc., 1984), j'ai commencé à écrire une routine similaire mais plus étendue en C.

Note : afin d'éviter les conflits de terminologie lorsqu'il est question de fonctions C et de fonctions mathématiques, les fonctions mathématiques seront ci-après appelées équations.

La routine qui résulte de mes efforts se compose de deux fonctions accessibles de l'extérieur et de nombreuses fonctions de soutien statiques. Toutes ces fonctions se trouvent dans un fichier intitulé FUNCEVAL.C et sont présentées dans le listing 1. Les deux fonctions accessibles de l'extérieur sont appelées "Convert" et "Evaluate". Convert transforme une chaîne contenant une équation mathématique en notation standard avec deux variables, X et Y, en une autre chaîne dont la notation peut être évaluée plus rapidement et plus efficacement. Evaluate accepte deux nombres à virgule flottante en double précision et renvoie la valeur de l'équation après avoir substitué ces deux valeurs à X et Y.

La fonction Convert se trouve vers la fin du listing 1. Le paramètre "FunctionString" est un pointeur vers une chaîne de caractères non signés à terminaison nulle. Cette chaîne doit contenir une équation mathématique dans deux variables, X et Y, et peut contenir l'un des nombreux appels de fonctions transcendantales et autres, tels que SIN, LN, SQRT, etc. Une liste complète des appels de fonction et des opérateurs mathématiques acceptables est présentée dans le tableau 1. FunctionString doit être en notation mathématique standard, comme l'illustre l'équation suivante.

-12.5 + SIN(X^2) / COS(LN(Y) + 2.2e-1)

FunctionString peut contenir un nombre quelconque d'espaces et les caractères alphabétiques utilisés pour les noms de fonctions et de variables qui peuvent être en majuscules ou en minuscules. Les deux premières fonctions d'assistance appelées par Convert, RemoveSpaces et strupr, suppriment tous les espaces de la chaîne et convertissent toutes les lettres minuscules en majuscules.

La fonction suivante appelée par Convert, CheckSyntax, examine la syntaxe de FunctionString. CheckSyntax peut détecter 12 erreurs syntaxiques différentes, telles que des caractères illégaux, des opérateurs mal placés et des parenthèses manquantes. Ces erreurs sont définies symboliquement dans le fichier d'en-tête SYNTXERR.H présenté dans le listing 2. Si une erreur est détectée, la variable globale SyntaxErr accessible de l'extérieur est assimilée à une valeur d'erreur appropriée et un pointeur vers le caractère incriminé dans FunctionString est renvoyé. Si aucune erreur n'est trouvée, SyntaxErr prend la valeur FALSE et un zéro est renvoyé.

Une fois que FunctionString a passé le contrôle syntaxique, elle est copiée dans une autre chaîne, fstr. Cela permet de conserver la forme originale de l'équation (sans espaces et avec tous les caractères alphabétiques en majuscules) dans FunctionString pendant que des modifications sont apportées à la copie dans fstr.

La première modification de fstr est effectuée par la fonction de gestion ConvertConstants. Cette fonction recherche initialement dans fstr les plus et les moins unaires et place un zéro devant le signe. Cette action facilitera le traitement ultérieur de la chaîne. Ensuite, ConvertConstants analyse à nouveau fstr en remplaçant toutes les constantes numériques par un symbole d'un octet compris entre 128 et 255 et en plaçant la valeur réelle de la constante dans un tableau pour référence ultérieure. Le nombre maximum de constantes autorisées dans la chaîne est de 128. Si fstr contient plus de 128 constantes, SyntaxErr est défini à TOOMANYCONSTS et FALSE est retourné, sinon TRUE est retourné.

La fonction suivante appelée par Convert, ConvertFunctions, analyse fstr et remplace tous les noms de fonctions transcendantales et autres par un symbole d'un octet compris entre 1 et 13. Ces symboles sont définis au début de FUNCEVAL.C. Aucune vérification d'erreur n'est nécessaire dans cette fonction car les fonctions illégales auront déjà été détectées dans CheckSyntax. Par conséquent, ConvertFunctions est une fonction nulle.

La dernière fonction de gestion appelée par Convert, InfixToPostfix, convertit fstr, qui est toujours en notation mathématique standard (avec des constantes et des noms de fonctions substitués par des symboles d'un octet), en une notation postfixe ou polonaise inverse. C'est la notation utilisée par le langage informatique Forth et par les calculatrices Hewlett-Packard. InfixToPostfix est une fonction relativement complexe qui lit la chaîne fstr caractère par caractère et, en fonction de la précédence des opérateurs, place le caractère dans la chaîne globale statique NewExpr ou le place sur une pile pour un traitement ultérieur. Si, au cours du traitement, la pile est débordée ou non, SyntaxErr sera assimilé à STACKUNDERFLOW ou STACKOVERFLOW et FALSE sera renvoyé. Lorsque le traitement est terminé, NewExpr contient l'équation mathématique en notation postfixe et renvoie TRUE.

Les fonctions Convert et ConvertConstants comportent plusieurs lignes de code qui ne seront compilées que si le symbole DEBUG est défini. Ces sections de code imprimeront l'équation à différents moments de son traitement. Examinons un exemple étape par étape. Supposons que la fonction telle qu'elle a été saisie à l'origine par l'utilisateur soit la suivante :

2.1E-1 + x*y - sin(-.8*X) / ln(+Y + 100)

Les étapes suivantes permettront de convertir cette fonction en forme symbolique avec la notation postfixe. La fonction de gestion qui accomplit chaque étape apparaît entre parenthèses.
  • Étape 1. Supprime tous les espaces (RemoveSpaces).

    2.1E-1+x*y-sin(-.8*X)/ln(+Y+100)
    

  • Étape 2. Convertis les lettres minuscules en majuscules (strupr).

    2.1E-1+X*Y-SIN(-.8*X)/LN(+Y+100)
    

  • Étape 3 : Vérifie la syntaxe. Si aucune erreur n'est détectée, le traitement se poursuit. Aucune modification n'est apportée à la chaîne de caractères (CheckSyntax).

  • Étape 4A. Mets des zéros devant les plus et les moins unaires (ConvertConstants).

    2.1E-1+X*Y-SIN(0-.8*X)/LN(0+Y+100)
    

  • Étape 4B. Remplace les constantes par des symboles d'un octet compris entre 128 et 255. Étant donné qu'il s'agit de caractères non imprimables, chaque caractère de la chaîne sera affiché ci-dessous sous forme de valeur décimale. Le caractère ou la constante qu'il représente apparaît sous la valeur décimale (ConvertConstants).

       128 43 88 42 89 45 83 73 78 40 129 45 130 42 88
    2.1E-1  +  X  *  Y  -  S  I  N  (   0  -  .8  *  X
    
    41 47 76 78 40 131 43 89 43 132 41
     )  /  L  N  (   0  +  Y  + 100  )
    

  • Étape 5. Remplace les noms de fonctions par des symboles d'un octet compris entre 1 et 13 (ConvertFunctions).

       128 43 88 42 89 45   1 40 129 45 130 42 88 41
    2.1E-1  +  X  *  Y  - SIN  (   0  -  .8  *  X  )
    
    47 12 40 131 43 89 43 132 41
     / LN  (   0  +  Y  + 100  )
    

  • Étape 6. Convertis la chaîne de caractères en notation postfixe (InfixToPostfix).

       128 88 89 42 43 129 130 88 42 45   1 131 89 43
    2.1E-1  X  Y  *  +   0  .8  X  *  - SIN   0  Y  +
    
    132 43 12 47 45
    100  + LN  /  -
    
La forme finale de l'équation de l'étape 6 réside dans la chaîne NewExpr. Un pointeur vers cette chaîne est renvoyé par Convert.

La fonction Evaluate, à la fin du listing 1, peut être utilisée pour évaluer l'équation à différentes valeurs de X et Y. Comme l'équation est maintenant en notation postfixe, Evaluate est une routine plutôt simple. Elle lit simplement les caractères de NewExpr de manière séquentielle ; si un caractère représente X, Y, ou une constante, sa valeur numérique réelle est poussée sur une pile. Si un caractère représente une fonction, Evaluate transmet le nombre en haut de la pile ainsi que le symbole du caractère représentant la fonction à la fonction Calculate. Le résultat de l'application de cette fonction au nombre sera renvoyé. Par exemple, si le nombre est égal à 100 et que la fonction est LOG, une valeur de 2 sera renvoyée. Cette valeur de retour est ensuite placée en haut de la pile.

Si un caractère représente un opérateur (^, +, -, *, /), les deux premiers chiffres de la pile et le symbole de l'opérateur sont transmis à Calculate. Le résultat de l'opération effectuée sur les deux nombres est renvoyé. Par exemple, si le nombre en haut de la pile est 24, que le nombre suivant sur la pile est 12 et que l'opérateur est "/", Calculate renvoie 12/24 ou 0,5. Notez que l'opération est toujours effectuée dans l'ordre suivant :

(Deuxième chiffre de la pile) opérateur (Premier chiffre de la pile)

La procédure ci-dessus se poursuit jusqu'à ce qu'il ne reste plus de caractères à lire dans NewExpr. À ce stade, la valeur de l'équation à laquelle ont été substituées les valeurs appropriées de X et Y se trouve sur le dessus de la pile. Cette valeur est retournée par Evaluate. Veuillez noter que Evaluate ne vérifie pas les opérations mathématiques illégales telles que la racine carrée d'un nombre négatif ou une multiplication qui provoque un débordement. La méthode de traitement de ces types d'erreurs varie selon les compilateurs. Il est laissé au lecteur le soin d'ajouter cette forme de gestion des erreurs si elle est nécessaire.

Un programme intitulé TESTFEVL.C est présenté dans le listing 3. Ce programme teste les fonctions Convert et Evaluate. L'utilisateur peut saisir une équation mathématique (jusqu'à 255 caractères) ainsi que les valeurs de X et Y ; le programme affichera le résultat de l'évaluation de l'équation. Malheureusement, la fonction "scanf" (de la bibliothèque C) ne permet pas de saisir des espaces dans une chaîne de caractères (ils sont utilisés comme délimiteurs) ; par conséquent, vous ne pourrez pas voir la fonction RemoveSpaces en action (remarque : si des espaces sont saisis comme partie de l'équation, le programme se comportera de manière erratique car les caractères après les espaces sont utilisés comme entrée pour les appels scanf ultérieurs). Si vous compilez FUNCEVAL.C avec "DEBUG" défini, chaque étape de la conversion de l'équation sera affichée sur la sortie standard. Vous pouvez jouer à votre guise. Assurez-vous de taper des équations syntaxiquement incorrectes pour voir comment fonctionne la détection des erreurs. L'équation sera affichée, une flèche vers le haut apparaîtra sous le caractère fautif, et un message d'erreur approprié sera imprimé.

FUNCEVAL.C et TESTFEVL.C sont écrits de manière générique et ont été compilés, liés et exécutés avec succès sur un Amiga 1000 utilisant Lattice C v4.01 et v5.02, sur un IBM AT utilisant Microsoft C v4.0, et sur un superordinateur Cray X-M/P utilisant le compilateur Cray (avec une modification). Si vous utilisez un compilateur C plus ancien, certaines des fonctions de la bibliothèque standard utilisées dans ce programme peuvent ne pas être disponibles.


[Retour en haut] / [Retour aux articles]