Les nombres entiers avec eFORTH
publication: 2 mars 2023 / mis à jour 2 mars 2023
Empilage et dépilage des nombres entiers
Le langage FORTH stocke les nombres sur une pile nommée pile de données ou pile paramétrique. L'empilage d'un nombre est très simple:
55
empile le nombre 55. Pour dépiler ce nombre, il y a plusieurs méthodes. La plus simple
consiste à afficher le contenu du dernier élément empilé. Le mot .
(point) affiche 55.
55 \ display ok . \ display 55 ok
Si vous déposez plusieurs nombres sur la pile de données, voici ce qui se passe:
11 45 6543?>
Les nombres sont mis sur la pile de données dans l'ordre de frappe. Le dernier nombre entré est toujours au sommet de la pile:
valeur empilée | haut -- pile -- fond |
---|---|
11 | 11 |
45 | 45 11 |
6543 | 6543 45 11 |
Le dépilage successif des nombres affiche ceux-ci dans l'ordre inverse de leur empilage:
11 45 6543 \ display ok . \ display 6543 ok . \ display 45 ok . \ display 11 ok
Pour mieux visualiser le mécanisme d'empilage et de dépilage des nombres, pensez à une pile d'assiettes: la dernière assiette déposée sur la pile sera la première reprise.
A tout moment vous pouvez prendre connaissance du contenu de la pile de données sans avoir
à provoquer le dépilage des valeurs qui y sont stockées en utilisant le mot .S
:
1 2 3 .S
affiche 1 2 3
Ce principe de rangement est appelé également pile LIFO (Last In, First Out) dans certains ouvrages écrits en anglais pour désigner une pile dont le mécanisme est: "dernier entré, premier sorti".
Avec la majorité des versions du langage FORTH, la quantité de nombres empilables est assez élevée, mais reste limitée. Si vous empilez trop de nombres, vous saturerez la pile de données. De même, toute tentative pour dépiler un nombre alors que la pile de données est vide, affichera un message d'erreur.
Chaque nombre empilé ne peut être qu'un nombre entier au format simple précision. Selon les cas, ce nombre peut être considéré signé ou non signé:
- signé ou non signé: paramètre de calcul arithmétique
- non signé: adresse simple précision intra-segment
En format simple précision signé, le bit de poids le plus fort indique le signe du nombre.
La valeur -1, déposée sur la pile en tant que valeur entière a la représentation binaire suivante:
11111111111111111111111111111111
(simple précision 32 bits).
Cette même valeur peut être affichée en valeur absolue en utilisant le mot U.
à la place du mot .
(point):
-1 U. \ affiche 4294967295
Opérations arithmétiques élémentaires
Les opérateurs arithmétiques + - *
et /
agissent sur les deux
valeurs situées au sommet de la pile de données. Les valeurs traitées sont toujours
des entiers simple précision signés.
Somme de deux nombres entiers
Pour additionner deux nombres, il faut d'abord les déposer sur la pile de données:
22 44 + .
affiche 66
Une fois empilés 22 et 44, le mot +
opère l'addition de ces deux
valeurs et le mot .
affiche le résultat:
55 1 + 3 + . \ affiche 59 et peut aussi s'écrire
55 1 3 + + .
L'addition est commutative: les valeurs peuvent être déposées sur la pile de données dans n'importe quel ordre:
55 22 + 22 55 +
Ce principe de calcul est appelé NOTATION POLONAISE INVERSE (RPN dans la littérature
anglaise, pour Reverse Polish Notation). On peut aussi additionner deux nombres
entiers non signés, à condition de visualiser le résultat à l'aide du
mot U.
au lieu de .
:
35000 10 + U.
Il est également possible de faire la somme de deux nombres de signe différent:
10 -5 + . \ affiche 5 -5 10 + . \ affiche aussi 5
Selon que l'on traite des valeurs considérées comme signées ou non, les intervalles de définition des résultats doivent respectivement se situer dans [- 32768..32767] ou [0..65535]. Tout résultat situé hors de ces intervalles n'aurait aucun sens.
FORTH dispose également du mot 1+
qui incrémente la valeur située
au sommet de la pile de données de 1 unité:
10 1+ \ est équivalent à
10 1 +
Soustraction de deux nombres entiers
Soit deux nombres a et b. La différence de deux nombres sera écrite en FORTH sous la forme:
a b -
pour a-b
La soustraction n'est pas commutative:
10 3 - . \ affiche 7 3 10 - . \ affiche -7
Le mot 1-
décrémente la valeur située au sommet de la pile de données de 1 unité:
10 1- \ est équivalent à
10 1 -
Produit de deux nombres entiers
Soit deux nombres a et b. Le produit de deux nombres sera écrit en FORTH sous la forme:
a b *
pour a*b
La multiplication est commutative:
7 5 * . \ ou 5 7 * . \ affiche 35
Le mot 2*
multiplie la valeur située au sommet de la pile de données par deux:
5 2* \ est équivalent à 5 2 *
Quotient de deux nombres entiers
Pour la division, seul le quotient entier est conservé sur la pile de données:
22 7 / . \ affiche 3
La division n'est pas commutative:
15 5 / . \ affiche 3 5 15 / . \ affiche 0
Le reste de la division peut être obtenu en appliquant la fonction modulo:
22 7 MOD . \ affiche 1
La fonction modulo peut servir à déterminer la divisibilité d'un nombre par un autre:
: DIV? ( n1 n2 ---)
OVER OVER MOD CR
IF
SWAP . ." n'est pas "
ELSE
SWAP . ." est "
THEN
." divisible par " . ;
Le mot /MOD
combine les actions de /
et de MOD
:
22 7 /MOD . . \ affiche 3 1
Produit et quotient de trois nombres
valable seulement pour les piles simple précision
Si on essaye une opération du type suivant:
30000 3 * 10 / .
on risque d'être quelque peu surpris par le résultat. Mais tout s'explique,
car le produit calculé en premier délivre une valeur dont la capacité est
supérieure à celle admise par les valeurs simple précision signées. Pour traiter
ces cas particuliers, on utilisera de préférence le mot */
qui combine les opérations de multiplication et de division, mais traite
le résultat transitoire de la multiplication au format double précision.
Exemple, soit à calculer le prix TTC d'une marchandise (TVA à 20 %), on définira le mot TTC comme suit:
: TTC ( n1 --- n2) DUP 200 1000 */ + ; 442 TTC . \ affiche 530
Les valeurs traitées étant exprimées en centimes.
Le mot */MOD
a les mêmes propriétés que */
, mais délivre
le quotient et le reste de l'opération.
A titre d'exemple, pour donner une application immédiate et pratique des notions déjà exprimées, est la conversion des degrés Fahrenheit et Celsius:
- la conversion des degrés Fahrenheit en degrés Celsius obéit à la formule
°C=(°F-32)*5/9 - la conversion des degrés Celsius en degrés Fahrenheit obéit à la formule
°F=9/5*°C+32
: C>F ( °C --- °F) 9 5 */ 32 + ; : F>C ( °F --- °C) 32 - 5 9 */ ; 37 C>F . \ affiche 98 (les résultats sont arrondis)
Cet exemple fonctionne sur toutes les versions du langage FORTH.
Traitement des expressions algébriques
Les opérations peuvent être chaînées, mais une opération en notation algébrique comportant des parenthèses doit être convertie en notation RPN en tenant compte de l'ordre de priorité des opérations. FORTH n'utilise pas les parenthèses dans les opérations arithmétiques:
soit l'expression algébrique ( 2 + 5 ) * ( 7 - 2 )
elle s'écrit en FORTH2 5 + 7 2 - *
Lors d'une opération de conversion de notation algébrique infixée en notation polonaise inverse, commencez toujours par le niveau de parenthèse le plus imbriqué et par la gauche. Ecrivez la transcription en notation polonaise inverse de chaque opération sur des lignes séparées, successivement de haut en bas, en les mettant dans le prolongement de l'expression algébrique exprimée dans la formule initiale:
En reprenant chaque niveau dans l'ordre, on réécrit la formule:<
 2 5 + 7 2 - * 5 2 + 3 * /
C'est choquant? Mais tous les interpréteurs/compilateurs travaillent ainsi lorsqu'ils ont à évaluer une formule algébrique. En notation algébrique, les parenthèses ne servent qu'à isoler une expression sous forme de sous-expression qui devient membre d'une expression plus générale.
En informatique comme en arithmétique, un opérateur travaille toujours sur deux opérandes et seulement deux opérandes simultanément. Le résultat d'une opération portant sur deux opérandes délivre une valeur qui peut devenir à son tour opérande d'un autre opérateur. L'ordre d'exécution des opérandes et des opérateurs est fondamental:
notation algébrique | polonaise inverse |
---|---|
(2+3)*5 |
2 3 + 5 * |
2+(3*5) |
2 3 5 * + or
3 5 * 2 + |
Tous les problèmes arithmétiques peuvent être résolus de cette manière, ce n'est qu'une question d'habitude. L'exemple donné précédemment illustre parfaitement la rigueur dont doit faire preuve le programmeurs Forth. Cette rigueur garantit un fonctionnement sans ambiguïté des programmes, quel que soit leur niveau de complexité.
Manipulation des données sur la pile
La pile de données est l'élément fondamental du langage FORTH pour le traitement de données. Son fonctionnement est identique à celui de la pile gérée par le micro-processeur. Dans certaines situations, les données traitées par les différentes définitions doivent être réordonnées ou dupliquées.
Le mot DUP
duplique le contenu du sommet de la pile de données:
10 DUP . . \ affiche 10 10 5 DUP * . \ affiche 25
Le mot OVER
duplique le second élément de la pile de données:
5 15 OVER . . . \ affiche 5 15 5
Le mot SWAP
inverse les deux éléments du sommet de la pile de données:
1 3 SWAP . . \ affiche 1 3
Le mot ROT
effectue une rotation sur les trois éléments situés au sommet de la pile de données:
1 2 3 ROT . . . \ affiche 1 3 2
Le mot -ROT
effectue une rotation inverse sur trois éléments. Son
comportement est similaire à l'exécution de deux ROT
successifs.
Le mot PICK
dépose au sommet de la pile de données le nième élément de la pile
de données, n non compris. La base de départ pour le comptage des éléments à traiter
est 0 et non 1, l'élément numéro zéro étant situé immédiatement après le paramètre
traité par PICK
. La séquence 0 PICK
est similaire à DUP
,
1 PICK
à OVER
. Il n'y a pas de traitement d'erreur si n est
supérieur au nombre d'éléments déposés sur la pile de données. Exemple:
1 2 3 4 5 6 4 PICK \ empile 2 car 6 est l'élément n°0, 5 l'élément n°1, etc...
Le mot ROLL
effectue une rotation sur les n premiers éléments
de la pile de données, n non compris. Comme pour PICK
, la base
de départ pour le comptage des éléments à traiter est 0:
1 2 3 4 5 6 4 ROLL . . . . . . \ affiche 2 6 5 4 3 1
Voici quelques exemples d'utilisation de ces manipulateurs de pile de données:
: AU-CARRE ( n --- n2)
DUP * ;
Le mot AU-CARRE élève un nombre entier quelconque au carré:
2 AU-CARRE . affiche 4
3 AU-CARRE . affiche 9
4 AU-CARRE . affiche 16
: AU-CUBE ( n --- n3)
DUP DUP * * ;
Le mot AU-CUBE élève un nombre entier quelconque au cube:
2 AU-CUBE . affiche 8 3 AU-CUBE . affiche 27
Attention, n'utilisez pas des valeurs trop élevées, car un résultat supérieur à 32767, pour une pile de données 16 bits, devient faux. Ayez toujours à l'esprit que les données traitées sont des entiers simple précision, donc de capacité limitée. Nous verrons ultérieurement comment traiter des nombres plus importants.
Passage de paramètres par la pile de retour
A coté de la pile de paramètres, il existe dans FORTH une deuxième pile, appelée pile de retour parce qu'elle sert à l'interpréteur interne à retrouver l'adresse de retour à chaque appel d'une procédure.
Il y a parfois des cas extrêmes où l'on peut être amené à stocker un ou plusieurs
paramètres ailleurs que sur la pile de données, ceci pour simplifier quelque
peu certaines manipulations scabreuses. la solution la plus commode, parmi d'autres,
est la pile de retour. Cette pile est accessible par les mots >R
et R>
moyennant quelques précautions pour ne pas compromettre le fonctionnement
de cette pile interne.
Le mot >R
transfère un nombre entier de la pile de données vers
la pile de retour.
Le mot R>
transfère un nombre entier de la pile de retour vers la pile de données.
Une opération >R R>
est nulle. En fin de définition, il doit y avoir
autant de >R
que de R>
sous peine de perturber quelque
peu le déroulement normal de votre définition. Exemple d'utilisation:
: AU-CARRE ( n --- n^2) \ élévation au carré DUP >R \ transfert de la copie sur pile de retour CR ." Le carré de " . \ affichage valeur initiale ." est " R> DUP * . ; \ récupération valeur déposée sur pile retour \ et affichage de son carré////
Contrôle de l'affichage des nombres entiers
En FORTH, les entiers simple précision déposés sur la pile de données peuvent être affichés
par exécution du mot .
(point). Mais d'autres mots permettent d'exécuter
un affichage plus présentable.
Le mot .R
affiche un nombre simple précision signé cadré à droite dans un champ de n caractères. Exemple:
3 10 .R
affiche 3 (3 précédé de 9 espaces)
101 10 .R
affiche 101 (101 précédé de 7 espaces)
Et dont voici une application très pratique:
: C>F ( °C --- °F) \ Conversion Celsius en Fahrenheit 9 5 */ 32 + ; : .TREMPE ( °C ---) \ Affiche °C et °F formatés DUP 6 .R ." °C " C>F 6 .R ." °F" ; : TREMPE-ACIER ( ---) \ Table des températures de trempe CR ." COULEURS DE TREMPE DE L'ACIER:" CR CR ." rouge foncé......... " 680 .TREMPE CR ." rouge cerise foncé.. " 740 .TREMPE CR ." rouge cerise........ " 770 .TREMPE CR ." rouge cerise clair.. " 800 .TREMPE CR ." rouge clair......... " 850 .TREMPE CR ." rouge très clair.... " 900 .TREMPE CR ." rouge jaune......... " 950 .TREMPE CR ." jaune............... " 1000 .TREMPE CR ." jaune clair......... " 1100 .TREMPE CR ." jaune blanc......... " 1200 .TREMPE CR ." blanc............... " 1300 .TREMPE CR CR ;
On exécute TREMPE-ACIER
:
trempe-acier COULEURS DE TREMPE DE L'ACIER: rouge foncé......... 680°C 1256°F rouge cerise foncé.. 740°C 1364°F rouge cerise........ 770°C 1418°F rouge cerise clair.. 800°C 1472°F rouge clair......... 850°C 1562°F rouge très clair.... 900°C 1652°F rouge jaune......... 950°C 1742°F jaune............... 1000°C 1832°F jaune clair......... 1100°C 2012°F jaune blanc......... 1200°C 2192°F blanc............... 1300°C 2372°F
Legal: site web personnel sans commerce / personal site without seling