APPLICATIONSDIVERS ★ LES OPERATEURS LOGIQUES AND, OR, XOR ET NOT ★

Operarateurs Logiques (CPC Infos)Applications Divers
Vous êtes débutant et aimeriez apprendre quand et comment manipuler ces entités mystérieuses ?

Vous programmez et pensez qu'il n'y a rien de plus à tirer des opérateurs logiques que ce qu'en dit le manuel Amstrad ? Tout le monde pourra trouver son profit dans ce qui va suivre, car ces opérateurs se prêtent à maintes applications, de la plus simple à la plus complexe. Encore faut-il comprendre l'essence même des opérations effectuées.

APPROCHE INTUITIVE

AND, OR et NOT signifient respectivement ET, OU et NON, ce qui veut dire exactement ce que ça a l'air de vouloir dire. Le XOR est un OU exclusif, nous l'examinerons plus loin.

Dans leurs applications les plus faciles à appréhender Intuitivement, ces opérateurs sont associés à des tests de condition (IF..THEN..ELSE) ou à des boucles fondées sur un test (WHILE..WEND). Prenons un exemple simple :
SI NOUS SOMMES SAMEDI OU DIMANCHE ALORS REPOS SINON AU BOULOT

et traduisons-le en Basic (A) :

10 IF JOUR$="samedi" OR JOUR$="dimanche" THEN PRINT "REPOS" ELSE PRINT "AU BOULOT !"

Tapez ensuite en mode direct : JOUR$="samedi":GOTO 10 et RETURN. Pourquoi GOTO et pas RUN ? Ah que voilà une question qu'elle est bonne : parce que RUN efface d'abord les variables en mémoire, donc JOURS et la valeur qu'on vient de lui affecter.

Le programme affiche «REPOS», OK. Exemple suivant :

SI NOUS SOMMES LUNDI ET SI JE SUIS MALADE ALORS REPOS SINON AU BOULOT

Traduit en Basic (B) :

10 IF JOUR$="lundi" AND MALADE$="oui" THEN PRINT "REPOS" ELSE PRINT "AU BOULOT !"

Tapez maintenant JOUR$="lundi":MALADE$="OUI": GOTO 10. Réponse : REPOS. Essayez

MALADE$="non":GOTO 10. Réponse : AU BOULOT ! Passons à autre chose :

SI NOUS NE SOMMES PAS SAMEDI OU DIMANCHE ALORS AU BOULOT SINON REPOS

Essayons de traduire cela en Basic (C) :

10 IF NOT JOUR$="samedi" OR NOT JOUR$="dimanche" THEN PRINT "AU BOULOT !" ELSE PRINT "REPOS"

Tapez JOUR$=»samedi»:GOTO 10. Réponse ; AU BOULOT I Ce n'est pas vraiment ce qu'on attendait.

SI l'exécution n'est pas correcte, c'est qu'il y a une erreur de logique dans l'expression de la condition globale. Il aurait fallu poser :

SI NOUS NE SOMMES PAS (SAMEDI OU DIMANCHE) ALORS AU BOULOT SINON REPOS

Ou bien encore :

SI NOUS NE SOMMES PAS SAMEDI ET SI NOUS NE SOMMES PAS DIMANCHE ALORS AU BOULOT SINON REPOS

Ce qui donne respectivement en Basic (D et E) :

10 IF NOT(JOUR$="Samedi" OR JOUR$="dimanche") THEN PRINT "AU BOULOT !" ELSE PRINT "REPOS"

10 IF NOT JOUR$="samedi" AND NOT JOUR$= "dimanche" THEN PRINT "AU BOULOT !" ELSE PRINT "REPOS"

Essayez à nouveau avec JOUR$="samedl" : cette fois c'est correct.

APPROCHE LOGIQUE

Comme leur nom l'indique, les opérateurs logiques relient deux opérandes (ou arguments) qui sont des valeurs logiques : VRAI ou FAUX. Par exemple, lorsque nous affectons à JOURS la valeur «samedi», la comparaison avec JOUR$=»samedi»? retournera la valeur logique VRAI. Ce sera la valeur logique FAUX pour la comparaison avec JOUR$=»dimanche»? Globalement, les choses se passent bien ainsi, et peu importe pour l'Instant la manière dont l'Interpréteur Basic s'y prend pour effectuer les comparaisons, et la nature exacte des valeurs logiques VRAI et FAUX.

Quelques exemples d'expressions logiques, avec leur résultat :

FAUX ET FAUX = FAUX FAUX OU FAUX = FAUX
FAUX ET VRAI = FAUX FAUX OU VRAI = VRAI NON VRAI = FAUX
VRAI ET FAUX = FAUX VRAI OU FAUX = VRAI NON FAUX = VRAI
VRAI ET VRAI = VRAI VRAI OU VRAI = VRAI

Tout ceci est évident ? Je suis heureux de vous l'entendre dire. Alors examinons sous cet angle nos 5 expressions logiques précédentes, repérées par les lettres A à E.

— Expression A
Avec JOUR$="samedi", nous obtenons :

SI VRAI OU FAUX ALORS REPOS SINON AU BOULOT
VRAI OU FAUX = VRAI, donc REPOS (la réponse qui suit ALORS).

— Expression B
Avec JOUR$="lundi" et MALADE$="oui", nous avons :

SI VRAI ET VRAI ALORS REPOS SINON AU BOULOT
VRAI ET VRAI = VRAI, donc REPOS.

Avec MALADE$="non", l'expression devient :
SI VRAI ET FAUX ALORS REPOS SINON AU BOULOT
VRAI ET FAUX = FAUX, donc AU BOULOT (la réponse qui suit SINON).

— Expression C
Avec JOUR$="samedi", cela donne :

SI NON VRAI OU NON FAUX ALORS AU BOULOT SINON REPOS

Autrement dit :

SI FAUX OU VRAI ALORS AU BOULOT SINON REPOS
FAUX OU VRAI = VRAI, donc réponse : AU BOULOT (celle qui suit ALORS).

Même si ce n'est pas ce que nous voulions obtenir, c'est parfaitement logique. C'est simplement l'expression qui était mal formulée.

— Expression D
Toujours avec JOUR$="samedi" :

SI NON(VRAI OU FAUX) ALORS AU BOULOT SINON REPOS

VRAI OU FAUX = VRAI et NON(VRAI) = FAUX, donc réponse : REPOS.

— Expression E
SI NON VRAI ET NON FAUX ALORS AU BOULOT SINON REPOS
SI FAUX ET VRAI ALORS AU BOULOT SINON REPOS
FAUX ET VRAI = FAUX, donc réponse : REPOS.

Même s'il s'agit du même signe «=», il ne faut pas confondre l'instruction d'affectation (celle qui nous permet d'attribuer une valeur à une variable) et l'opérateur relationnel d'égalité. Pour mieux vous mettre le nez sur le problème, tapez :

A=5:PRINT A;A=5;A<>5 et RETURN. Réponse : 5 -1 0.

Je vous expliquerai ce -1 et ce 0 en temps utile. Les OPERATEURS RELATIONNELS (=, >, <, >=, <= et <>) font toujours partie d'une condition, annoncée généralement (mais pas obligatoirement) par IF ou WHILE. L'ambiguïté du signe «=» est une source regrettable de confusion, même si l'interpréteur Basic, lui, ne s'y trompe pas. Les autres langages évitent généralement ce piège.

Dans l'évaluation d'une expression conditionnelle, l'Interpréteur calcule d'abord le résultat logique des opérations relationnelles s'il y en a (c'est-à-dire compare ces expressions avec la valeur courante des variables concernées), puis effectue sur ces résultats les opérations logiques éventuelles, et enfin retourne un résultat unique. SI c'est VRAI, ce sont les Instructions précédées de «alors» (THEN) qui sont exécutées. Dans le cas contraire, l'Interpréteur exécute ce qui suit «sinon» (ELSE), ou en son absence les Instructions de la ligne suivante.

Comme en algèbre, le résultat des expressions entre parenthèses est calculé en priorité. Au moindre doute sur l'ordre des opérations, usez et abusez des parenthèses. Sans parenthèses, l'ordre de priorité est le suivant : (=,>,<,>=,<=,<>) > NOT > AND > OR > XOR.

Je ne vous al pas encore expliqué le OU exclusif (XOR). Il retourne VRAI seulement si les 2 opérandes logiques ont des valeurs opposées, en d'autres termes si un seul d'entre eux est VRAI :

FAUX XOR FAUX = FAUX
FAUX XOR VRAI = VRAI
VRAI XOR FAUX = VRAI
VRAI XOR VRAI = FAUX

Au XIXe siècle, le mathématicien anglais George BOOLE eut l'idée de rapprocher les mathématiques et la logique. Il formalisa les opérations logiques telles que celles expliquées ici, et créa une algèbre, l'algèbre de Boole, permettant de les représenter. C'est pourquoi, dans certains langages Informatiques, les opérateurs logiques sont également appelés opérateurs booléens, et les valeurs VRAI et FAUX sont dites de type booléen (True et False en Pascal, .T. et .F. en dBase).

En algèbre de Boole, aux valeurs logiques VRAI et FAUX sont respectivement liées les valeurs numériques 1 et 0. Ceci permet de représenter les opérations logiques sous forme de TABLES DE VERITE , d'un aspect tout à fait analogue à nos bonnes vieilles tables de multiplication.

AND10 OR10 XOR10NOT 1 = 0
NOT 0 = 0
110111101
000010010

On prend un opérande à gauche sur une ligne, l'autre en haut sur une colonne, et on lit le résultat de l'opération logique à l'Intersection de la ligne et de la colonne.

L'opérateur NOT ne porte que sur un seul opérande ; il transforme 1 (VRAI) en 0 (FAUX) et vice versa : c'est un Inverseur logique.

ATTENTION : les valeurs 1 et 0 ne sont pas des valeurs décimales, ce sont des VALEURS BINAIRES. L'algèbre de Boole est une algèbre binaire. Avant d'aller plus loin, il est nécessaire d'expliquer (ou de réexpllquer ?) de quoi il retourne.

LES NOMBRES BINAIRES

Le sujet a déjà été traité maintes fois dans cette revue, dans d'autres contextes. Aussi serai-je le plus bref possible.

Un nombre est représenté au moyen de chiffres : 0 à 9 en décimal, 0 à 1 en binaire. Quel que soit le système employé, chaque chiffre utilisé dans la représentation d'un nombre possède un poids, qui est fonction de son rang, en partant de la droite.

Exemple : 123 en décimal représente 1 centaine + 2 dizaines + 3 unités. 3, premier en partant de la droite, possède le poids le plus faible (unités), et 1, au troisième rang (celui des centaines), possède le poids le plus fort. Par ailleurs, vous conviendrez que :

123 = Autrement dit, la valeur d'un nombre décimal est la somme des produits de chacun des chiffres par son poids. Et le poids d'un chiffre, toujours en décimal, c'est 10 élevé à la puissance n, n étant le rang du dit chiffre dans le nombre, de la droite vers la gauche, en comptant à partir de zéro.

Accrochez vos ceintures et éteignez vos mégots, on aborde l'étape suivante. Le système décimal est dit en base 10, et le système binaire en base 2 (d'où son nom). Oyez : quel que soit le système employé, le nombre de chiffres différents possibles est égal à la base. Par ailleurs, le poids d'un chiffre dans un nombre est égal à la base, élevée à une puissance qui est le rang du chiffre compte depuis la droite du nombre, le premier rang étant zéro.

Un ordinateur ne sait gérer que le système binaire (2 chiffres possibles : 1 et 0). Pour lui, si le courant passe c'est 1, s'il ne passe pas c'est 0. Simple, non ? Ces 1 et ces 0 sont appelés des bits (pas de ricanements au fond de la classe, SVP), abréviation de binary dlgits. ce qui signifie chiffres binaires.

En informatique, les bits sont regroupés par 8, ce qui donne un octet. Le CPC est un ordinateur 8 bits, car il manipule les données sous forme de nombres binaires de 8 bits. Les compatibles PC, Atari, Amiga, etc... sont des 16 bits, ils traitent 2 octets à la fois.

Examinons un octet, donc 8 bits alignés. Le poids du bit le plus à droite est égal à la base, soit 2, élevée à la puissance du rang, soit 0. Le poids du bit le plus à gauche est 2 élevé à la puissance du rang, donc 7 (0 à 7 font bien 8 rangs, OK ?). Voyons cela de plus près :

Rang 7 6 5 4 3 2 10
Poids 27 26 25 24 23 22 21 20
128 64 32 16 8 4 2 1

Vous voyez en bas les poids traduits en valeurs décimales.

Première remarque : chaque poids est égal au précédent (depuis la droite) multiplié par 2, c'est-à-dire par la base. C'est pareil en base 10 (décimal) : le poids du rang des milliers est égal au poids du rang des centaines multiplié par 10.

Seconde remarque : chaque poids est égal à la somme de tous les précédents (toujours en partant de la droite) plus 1.

Pour calculer la valeur décimale d'un octet, c'est très simple : on multiplie chaque bit par son poids, et on fait la somme.

Exemple : 01101110

(0*128)+(1*64)+(1*32)+(0*16)+(1*8)+(1*4)+(1*2)+(0*1)
64+32+8+4+2 =110

il y a des raccourcis commodes, dans certains cas particuliers :

00000000 = 0
11111111 = 128+( 128-1) = 255
00011111 = 16+(16-1) = 31

Pour les 2 derniers exemples, rappelez-vous la seconde remarque.

Tout ceci pour vous faire bien comprendre la structure des nombres binaires. Je ne vous propose pas d'exercices de conversion binaire-décimal et décimal-binaire, ça ne présente aucun intérêt car l'Amstrad fait cela 1000 fois plus vite que vous. Ce que je vous recommande vivement, par contre, c'est d'appeler la fonctlon'BINS pour une conversion déclmal-blnalre, et d'examJner avec soin le résultat, chaque fols que vous avez à résoudre un problème où c'est la représentation -binaire des nombres qui est importante. Et c'est bien le cas avec les opérateurs logiques.

Quelques définitions utiles avant de passer à la suite. On dit qu'un bit est mis lorsqu'il est à 1. Les entiers occupent 2 octets, soit 16 bits. Le 16ème bit, c'est-à-dire le bit 15, le plus à gauche, est le bit de signe ; les autres sont les bifide données. Si le bit de signe est mis (s'il est égal àl ), l'entier est négatif ; sinon l'entier est positif. C'est pourquoi la valeur d'un entier ne peut être comprise qu'entre 32767 et -32768 inclus.

Une telle représentation des entiers signés est dite représentation en complément à 2. Pour rendre négatif un entier, le système Inverse un par un tous les bits (1 devient 0, et 0 devient 1 : complément à 1), puis ajoute 1 (complément à 2).

1 décimal = 00000000 00000001 binaire
inversion : 11111111 11111110
+ 1 = 11111111 11111111 binaire = -1 décimal

Notez que -1 est représenté en binaire par un nombre où tous les bits sont mis. Nous aurons l'occasion d'y revenir.

BAS LES MASQUES

imaginez un nombre binaire écrit sur une feuille de papier, et une réglette en carton percée d'une petite fenêtre magique. Vous faites glisser la réglette sur le nombre, jusqu'à encadrer dans la fenêtre le bit choisi, et vous pouvez alors déterminer son état (1 ou 0), l'inverser, ou le forcer au choix à 1 ou à 0, quel que sôit son état. C'est ce qu'on appelle un MASQUE et c'est exactement ce qu'on peut réaliser avec les opérateurs logiques.
ils vous donnent en effet accès à des opérations individuelles sur les bits, directement à partir du Basic.

C'est-y pas fabuleux ?

Précisons tout de suite que les opérations logiques sur les nombres ne fonctionnent que sur les entiers, pas sur les réels (qui sont représentés sur 5 octets au lieu de 2). Examinons quelques exemples (sur un seul octet pour plus de simplicité). (Voir figure 1).

Et sur 2 octets, par exemple avec des nombres négatifs :

NOT -1 = 0 NOT 0 = -1 NOT 1 = -2

-1 : 13111111 11111111 1:00000000 00000001

0 : 00000000 00000000 -2 : 11111111 11111110

-2 est le complément à 1 de 1 (inversion de chaque bit). Notez que. quel que soit l'entier A, NOT A = -(A+1) : c'est une autre manière de représenter le complément à 1. SI on ajoute 1 à -2, on obtient bien -1 (complément à 2 de 1), en décimal comme en binaire. Toujours quel que soit A, complément à 2 de A = complément à 1 de A. plus 1 = -(A+l)+1 = -A. D'accord ? Par ailleurs :

NOT(A XOR -1) = A avec ou sans parenthèses, car (NOTA) XOR -1 = A
En fait, NOT A = A XOR -1, donc NOT(NOT A) = (A XOR -1) XOR -1 =A

Après ce petit hors-d'œuvre, vous avez tous compris comment ça tourne. Mais si, mais si. Nous allons maintenant pouvoir passer en revue ce qu'il est possible de faire concrètement avec les opérateurs logiques.

Soit A un entier signe quelconque. A étant représenté sur 2 octets, soit 16 bits, appelons N le bit sur lequel nous voulons travailler. N peut prendre toute valeur de 0 à 14 ; gardons-nous bien de toucher au bit 15 (le 16ème, c'est-à-dire le bit de signe), sinon gare aux résultats aussi étranges qu'inattendus. Comme nous l'avons vu précédemment, 2N représente le poids du bit N, ou sa valeur s'il est mis.

  • A OR 2N force le bit N de A à 1, quel que soit son état antérieur (1 ou 0). A + 2N ne fait la même chose que si le bit N est à 0.
  • A AND (-1 -2N) force le bit N de A à 0, quel que soit son état antérieur (1 ou 0). A - 2N ne fait ia même chose que si le bit N est à 1.
  • A AND 2N = 2N si le bit N est à 1, sinon A AND 2N = 0.
  • A XOR 2N Inverse le bit N (et lui seul). Le bit N est force à 1 si son état antérieur est 0, il est forcé à 0 si son état antérieur est 1.

Soit A une variable entière, Initlalisée à 0 (ou pas Initlalisée du tout, ce qui en Basic revient au même). L'instruction A = A XOR 1, chaque fois qu'elle est exécutée, fait passer la valeur de A de 0 à 1, et vice versa. Cela peut être commode pour un flag à 2 valeurs, du genre oui/non, vrai/faux. Un flag (drapeau en anglais) est un indicateur d'état, une variable pouvant prendre un petit nombre de valeurs bien définies, généralement 2 : drapeau levé ou drapeau baissé. Mais l'Intérêt principal de cette instruction est de permettre, avec une économie maximum de moyens, la construction d'une BASCULE.

Un logiciel ayant 2 modes de fonctionnement utilise une bascule (toggle dans les produits d'Outre-Manche) pour passer d'un mode à l'autre, par exemple le choix entre Joystick et clavier dans un jeu. En fait, une vraie bascule permet de changer de mode à tout moment, autant de fols qu'on veut ; exemple : la bascule insertion/recouvrement dans les traitements de texte.

Comment ça marche ? Une touche ou une combinaison de touches particulières, dans le module de scrutation du clavier, appelle le sous-programme contenant l'Instruction A = A XOR 1, puis le sous-programme de configuration ad hoc, par exemple par l'Instruction :

ON A+1 GOSUB ...

En graphisme, XOR a également une application très importante : le mode XOR graphique (voir l'article de Guy Poli dans Amstar & CPC No 27 de novembre-décembre 1988). Ce mode est instauré par PRINT CHR$(23); CHR$(1);:TAG pour les caractères ASCII, ou en fixant à 1 le 4ème paramètre des Instructions graphiques (sur 6128 seulement). Entre autres effets du plus haut Intérêt, Il permet, dans les animations, d'effacer un objet en le réaffichant simplement à son emplacement courant, et de le faire passer au choix devant ou derrière un autre objet.

LES MYSTERES DE LA LOGIQUE

Initialisons d'abord 2 variables : JOURS$="samedi" et A%=5.

1 ) Expression conditionnelle annoncée par IF ou WHILE

a) Comparaison explicite d'une expression relationnelle avec la valeur de la ou des variables concernées.

Exemples i

IF JOUR$="samedi" THEN PRINT"VRAI" ELSE PRINT "FAUX"
IF A%=5 THEN PRINT "VRAI" ELSE PRINT "FAUX"

La comparaison retourne l'entier -7, c'est-à-dire VRAI.

Exemples :

IF JOUR$="dimanche" THEN PRINT "VRAI" ELSE PRINT "FAUX"

IF A%=1 THEN PRINT "VRAI" ELSE PRINT "FAUX"

La comparaison retourne l'entier 0 , c'est-à-dire FAUX.

VRAI est associé à 1 et FAUX à 0, mais ce 1 et ce 0 sont des bits. L'entier 0 est un nombre binaire dont tous les bits sont à 0. L'entier -1 est un nombre binaire dont tous les bits sont à 1 : plus vrai que ça tu meurs 1 C'est ainsi que le système (qui ne sait manipuler que des 1 et des 0, enfonçons le clou...) représente le résultat logique d'une expression conditionnelle, en mettant tous les bits d'une variable Interne à 1 ou à 0, selon aue ce résultat est VRAI ou FAUX.

Dans une expression conditionnelle complexe comprenant des expressions relationnelles liées par AND. OR ou XOR (avec ou sans NOT, avec ou sans parenthèses), ceux-ci effectuent tout simplement des opérations loglaues sur les résultats numériques (-1 ou 0) des expressions relationnelles. Le résultat final unique est soit -1, soit 0, ce qui détermine l'orientation du programme consécutive au test.

b) Comparaison implicite (sans opérateur relationnel) de chaque bit de la valeur d'une variable ou du résultat d'une expression algébrique (Ex. A+B-3) ou logique (Ex. A AND B), avec 1.

Exemple :

IF A%=5 THEN PRINT "VRAI" ELSE PRINT "FAUX"

  • Si le résultat de l'expression est égal à 0 (tous les bits à 0), le résultat ae la comparaison est 0 (FAUX). C'est ce que nous obtenons puisque A%=5.
  • SI le résultat de l'expression n'est pas nul (au moins 1 bit à 1). le résultat de la comparaison est -1 (VRAI).

Exemple :

IF NOT A% THEN PRINT"VRAI" ELSE PRINT "FAUX"

  • SI A%=-1, NOT A%=0, donc le résultat de la comparaison est 0 (FAUX).
  • Pour toute valeur de A% différente de -1, NOT A% est différent de 0. donc le résultat est -1 (VRAI).

Cette instruction n'affichera FAUX que si A%=-1, et VRAI dans tous les autres cas.

Pour un fonctionnement sans bavures de ce genre de test, il vaut mieux que A% soit un flag à 2 valeurs possibles, -1 ou 0. Initialisé à -1, le flag est «mis», à l'endroit ad hoc du programme, par l'Instruction A%=NOT A% : c'est une autre forme de BASCULE.

Vous l'avez compris, la comparaison implicite est :

IF (expression/variable) <> 0 THEN...

ATTENTION : NE JAMAIS CONFONDRE LE RESULTAT NUMERIQUE DE L'EXPRESSION ET LE RESULTAT DE LA COMPARAISON.

2) Expression conditionnelle sans IF ni WHILE, mais avec opérateurs) relatlonnel(s)

Soit A%=5, PRINT A% affichera 5, OK. Mais nous avons vu plus haut que PRINT A%=5 affiche -1, et que PRINT A%<>5 affiche 0. Dans ce cas, les règles de la syntaxe indiquent à l'interpréteur que le signe «=» n'est pas l'opérateur d'affectation, mais un opérateur relationnel faisant partie d'une expression dont II doit calculer le résultat logique, par comparaison avec la valeur de la variable contenue dans l'expression. Comme A% vaut 5, le résultat est -1 (VRAI) dans le premier cas, et c'est bien ce qu'affiche la commande PRINT. Même chose pour l'autre exemple, à ceci près qu'il n'y a aucune ambiguïté sur la nature de l'opérateur, Ces expressions particulières entrent dans la construction d'instructions aussi concises que puissantes, exprimées sous forme de relations «d'allure algébrique». Incluant en fait des conditions. Les paramètres en entrée sont de type numérique ou chaîne de caractères ; le résultat en sortie est toujours numérique. Quand les utilise-t-on ?

  • Lorsqu'il est Impossible d'employer IF...THEN ou WHILE :
  • dans une formule algébrique,
  • dans une fonction utilisateur.
  • Lorsqu'on recherche la concision dans l'écriture : cas des tests multiples (avec plusieurs IF...THEN...ELSE en cascade).

Exemple : fonction utilisateur testant un bit quelconque d'une variable entière, directement à partir du Basic. En entrée : A est un entier signe, N est le numéro du bit à tester (0 à 15). Résultat en sortie : état du bit N (1 ou 0).

DEF FNbit(A,N)=((A AND 2N)>0)

Application : A=132:N=7:PRINT FNbit(A,N) → 1,

Explication : 2N = 27 = 128

132 AND 128= 128

128 > 0 = VRAI = -1, aonc résultat = 1.

Nota : le signe «-» peut être remplacé par la fonction ABS (valeur absolue).

Dans cet exemple (et la plupart du temps), attention aux parenthèses 1 Avec les mêmes variables, -(A AND 2N>0) donnera :

2N > 0 = VRAI, donc résultat = -1

A AND -1 = 132

Résultat = -132 !

-A AND 2N>0 donnera aussi comme résultat -132.

APPLICATIONS

Un programme doit parfois déterminer si un nombre entier, à priori inconnu, est pair ou impair. Un nombre pair, divisé par 2, fournit un dividende entier, donc sans reste, il y a plusieurs solutions :

PairImpair
A/2-INTCA/2) =00.5
(A/2=INT(A/2))=-10
A MOD 201
A AND 101

La dernière instruction est la plus rapide ; son principe est différent ; elle teste simplement le bit 0.

Avant d'envoyer des données à l'imprimante, un programme peut s'assurer qu'elle est prête à les recevoir. Par le port 8;F532 (en hexadécimal), l'Imprimante envole à l'ordinateur un nombre sur 2 octets qui représente son état. Le bit 6 de ce nombre correspond à la broche BUSY (occupé), Le test est très simple :

A=INP(&F532):B=A AND 64 (64 = 26)
B = 64 → bit 6 à 1 → OFF LINE (tampon plein, ou pas de papier)
B = 0 → bit 6 à 0 → ON LINE (Imprimante prête à recevoir les données).

Le seul point noir au tableau, c'est que le bit 6 est aussi à 0 lorsque l'imprimante est éteinte, et qu'il n'existe aucun moyen, pour un programme, de faire la différence avec l'état ON LINE. No comment. Mister SUGAR ?

Le LISTING 1 est une sorte de Shoot'em Up. Principe : apparition, en un point aléatoire de l'écran (ligne 70), d'un «monstre» agité de mouvements imprévisibles ; en un temps limité, il faut descendre le bestiau en déplaçant une mire située initialement au centre de l'écran (60). Ce n'est pas PROHIBITION, mais cela montre ce qu'on peut faire rien qu'avec du Basic, en utilisant à bon escient les opérations logiques, et quelques autres astuces.

En 90, boucle d'attente classique. En 140, boucle principale du programme.

Le mode XOR graphique (nécessaire à l'animation) est Instauré en 100 pour l'affichage des caractères (monstre = CHRS(225)) et en 340 pour celui du viseur. Sur 464, il faut supprimer le 4ème paramètre de la commande MOVE en 340 et en 420, et ajouter POKE &B291.1.

Déplacements du monstre : horizontal en 210, vertical en 220. Affichage en 270, effacement en 200. Déplacements du viseur ; horizontal en 350, vertical en 360. Affichage en 420. effacement en 340. Test de la touche FIRE en 370 et 430 (retourne 0 ou 16) et de la concordance du point visé avec la surface sensible de la cible en 480 (on peut réduire cette surface pour rendre le jeu plus difficile).

Ni le viseur ni le monstre ne peuvent sortir de l'écran (380 à 410, et 230 à 260).

Le principe est très simple. Voyons d'abord l'interprétation des actions sur le joystick pour le déplacement du viseur.

La fonction JOY(0) retourne un nombre sur un octet, dont les bits représentent les actions exercées sur le joystick 1 ; pour le joystick 2, ce sera JOY(l). Seuls les 5 premiers bits (0 à 4) sont significatifs.

No du bit43210
Poids168421
ActionFireDroiteGaucheBasHaut

Toutes les combinaisons sont bien sûr possibles. Exemple : JOY(0)=26 -> Fire + Droite + Bas. Comment tester l'état des différents bits ? C'est très facile et très rapide avec AND.

Si nous poussons le joystick à Droite, JOY(0) AND 8 donne 8, et 8*2=16. La position d'affichage est donc décalée de 16 points à droite. Si nous le poussons à Gauche, le déplacement est retranché de la position courante. Fonctionnement analogue pour Haut et Bas. Comme je suis flemmard. J'ai gardé le même principe pour les déplacements du monstre. En 180, le système tire un nombre m au hasard, entre 1 et 10 inclus. J'ai décidé arbitrairement de la correspondance suivante :

No du bit3210
Poids8421
ActionHautBasDroiteGauche

Le nombre m est ensuite testé par un AND, comme pour JOY(O). il y a une valeur de m correspondant à un déplacement nul : c'est 3 (Gauche et Droite à la fois).

Plus qu'une démo, le LISTING 2 est un véritable utilitaire. il affiche un catalogue déroulant de la disquette, pour l'USER de votre choix, et vous offre le lancement ou le chargement d'un programme Basic ou Binaire, ou l'affichage du contenu d'un fichier ASCII. Bien entendu, les commandes non appropriées au type de fichier sélectionné sont détournées à la source. SI vous changez de disquette, tapez «U» puis le No d'User pour appeler le nouveau catalogue.

Le choix du fichier et le choix de la commande se font à l'aide des mêmes touches (flèches haut et bas). Les touches flèches gauche et droite servent à basculer d'un mode à l'autre.

Au lancement, on est en mode «Choix Commande». En 90, on initialise donc bascule à 1 et x à 25 (coordonnée d'affichage du mode actif). SI on change de mode (330 et 400-410), bascule prend la valeur 0 et x la valeur 10. SI on change à nouveau, bascule = 1 et x = 10+15 = 25 (car le test bascule = 1 retourne la valeur -1 -> VRAI).

En fonction de la valeur de bascule, flèche haut et flèche bas font défiler la barre de choix, soit sur le catalogue (680 à 750), soit sur le menu de commandes (790 à 820).

La boucle de scrutation du clavier (290 à 340) utilise la fonction INKEYO plus rapide que INKEYS, mais plus chatouilleuse aussi ; d'où les CLEAR INPUT qu'on trouve un peu partout. Il faut même parfois ralentir (boucle d'attente en 800 et surtout en 400, Inaispensable), INKEY() retourne -1 tant que la touche correspondante n'est pas pressée, 0 si elle est pressée seule, 32 avec SHIFT, 128 avec CONTROL. et 160 avec SHIFT et CONTROL. NOT INKEY() sera donc FAUX si INKEY() retourne -1, et VRAI dans tous les autres cas : l'instruction précédée de THEN sera alors exécutée.

Dès qu'on appuie sur ENTER ou RETURN (290), on sort de la boucle de scrutation, et la ligne 350 est exécutée. Après exécution de la commande «Afficher ASCII», ou après une erreur sur le type de fichier, on retourne à la boucle sans fin. La comparaison sous-entendue dans l'instruction WHILE sansfin retourne toujours vrai, puisque sansfin n'est Jamais annulée. Ceci évite un GOTO.

La variable iop (indice option) sert à la fois :

  • à désigner la coordonnée verticale d'affichage de l'option courante du menu et son libellé (790),
  • à calculer la nouvelle coordonnée et le nouveau libellé après action sur flèche haut ou flèche bas (810-820),
  • à déterminer ce que doit faire le programme après validation (350 et 880).

La ligne 860 est destinée à vous éviter des ennuis si le programme lancé doit faire des allocations mémoire (SYMBOL AFTER ou MEMORY).

Vous pouvez appeler ce programme «M.BAS» et le sauver dans toutes vos disquettes. Il vous suffira de taper RUN"M" pour disposer d'une fonction Catalogue (très) améliorée. Si vos disquettes sont bourrées en vrac, pourquoi ne pas répartir les fichiers par familles, dans les différents Users ?

CPCINFOS

★ EDITEUR: CPCINFOS
★ ANNÉES: 1990 , 1991
★ CONFIG: 64K + AMSDOS
★ LANGAGE:
★ LiCENCE: LISTING
★ AUTEUR: Guy DUBUS
 

★ AMSTRAD CPC ★ DOWNLOAD ★

Type-in/Listing:
» Operarateurs  Logiques    (CPC  Infos)    LISTING    FRENCHDATE: 2021-04-19
DL: 126
TYPE: PDF
SiZE: 645Ko
NOTE: |DEK|2 pages/PDFlib v1.6

★ AMSTRAD CPC ★ A voir aussi sur CPCrulez , les sujets suivants pourront vous intéresser...

Lien(s):
» Applications » Professionelles Astrologie-Programm
» Applications » Numérologie (CPC Revue)
» Applications » Météorologie
» Applications » Gestion de Logiciel
» Applications » Mini C.A.O : Conception Assistée par Ordinateur (Logistrad)
» Applications » Logiciel de Gestion Informatisee Pour Amstrad CPC464
Je participe au site:
» Pour ce titre nous ne disposons de fichier executable sur CPC (Dump, Saisie du listing) , alors si vous avez ça dans vos cartons ou vous désirez usé vos petit doigts boudinés sur votre clavier faites le nous savoir.
» Vous avez des infos personnel ?
» Vous avez remarqué une erreur dans ce texte ?
» Aidez-nous à améliorer cette page : en nous contactant via le forum ou par email.

CPCrulez[Content Management System] v8.7-desktop/c
Page créée en 414 millisecondes et consultée 704 fois

L'Amstrad CPC est une machine 8 bits à base d'un Z80 à 4MHz. Le premier de la gamme fut le CPC 464 en 1984, équipé d'un lecteur de cassettes intégré il se plaçait en concurrent  du Commodore C64 beaucoup plus compliqué à utiliser et plus cher. Ce fut un réel succès et sorti cette même années le CPC 664 équipé d'un lecteur de disquettes trois pouces intégré. Sa vie fut de courte durée puisqu'en 1985 il fut remplacé par le CPC 6128 qui était plus compact, plus soigné et surtout qui avait 128Ko de RAM au lieu de 64Ko.