Opérations logiques sur les nombres entiers.
Si vous connaissez bien le système binaire, vous pouvez sauter le tableau de correspondance suivant:
décimal | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
binaire | 0 | 1 | 10 | 11 | 100 | 101 | 110 | 111 | 1000 |
décimal | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | |
binaire | 1001 | 1010 | 1011 | 1100 | 1101 | 1110 | 1111 | 10000 | |
décimal | -1 | -2 | -3 | -4 | -5 | -6 | |||
binaire | ...1111 | ...1110 | ...1101 | ...1100 | ...1011 | ...1010 |
La dernière ligne du tableau représente quelques nombres binaires négatifs:
... représente, ici, une suite de 1 vers la gauche (c'est le signe moins).
Le nombre de 1 dépend de l'implémentation: sur 8, 16, 32, 64 bits.
Pour avoir la valeur absolue de ce nombre négatif, on prend le complément et on lui ajoute 1.
Exemple: pour -5, on prend le complément de ...1011, soit 100 et on lui ajoute 1: 101, donc 5 dans le système décimal.
Un truc aussi: en remarquant que -5=-8+3, en binaire cela fait ...111011=...111000+11.
Ce qui nous inspire la décomposition du nombre ...111011 de la façon suivante:
...11 | 1000 | 11
- 8 +3 donc -5
L'écriture et le calcul sont un peu déroutants, mais pensez bien que: (...111011)-(...111000)= 11 ne
peut être que positif (le plus grand moins le plus petit).
Les 4 fonctions suivantes sont associatives, on peut donc leur donner plus de 2 arguments:
Par exemple: (logior 2 (logior 3 4)) = (logior (logior 2 3) 4) = (logior 2 3 4) = 7
LOGIOR:
(logior 2 3 4 5)
7 10 ou 11 ou 100 ou 101 donne bien 111 en binaire
(logior)
0 c'est l'identité pour cette opération
LOGXOR:
(logxor 2 3 7)
6 10 ou(excl) 11 donne 1 et 1 ou(excl) 111 donne 110
(logxor)
0 c'est l'identité pour cette opération
LOGAND:
(logand 2 3 6)
2 10 et 11 et 110 donne 10
(logand)
-1 c'est l'identité pour cette opération
LOGEQV:
(logeqv 2 3)
-2 équivaut à un non-xor (non-ou-exclusif): 10 non-xor 11 donne non(01), soit ...11110, donc -2
(logeqv)
-1 c'est l'identité pour cette opération
NEGATION d'une valeur logique:
LOGNOT: (ne prend qu'un argument et rend le complément de cet argument)
(lognot 0)
-1 ...1111111 se note -1
de même: ...1111110 se note -2 = (lognot 1)
...1111100 se note -4 = (lognot 3)
...1111101 se note -3 (-4+1) = (lognot 2)
Les 6 fonctions suivantes ne sont pas associatives, elles prennent donc exactement 2 arguments:
LOGNAND:
LOGNOR:
LOGANDC1:
LOGANDC2:
LOGORC1:
LOGORC2:
Voici la table de vérité des 10 opérations logiques agissant sur 2 arguments:
entier1 | 0 | 0 | 1 | 1 | 3 | |
---|---|---|---|---|---|---|
entier2 | 0 | 1 | 0 | 1 | nom de l'opération | 5 |
logand | 0 | 0 | 0 | 1 | ET | 1 |
logior | 0 | 1 | 1 | 1 | OU (inclusif) | 7 |
logxor | 0 | 1 | 1 | 0 | OU (exclusif) ou XOR | 6 |
logeqv | 1 | 0 | 0 | 1 | équivalence (NON-XOR) | -7 |
lognand | 1 | 1 | 1 | 0 | NON-ET | -2 |
lognor | 1 | 0 | 0 | 0 | NON-OU | -8 |
logandc1 | 0 | 1 | 0 | 0 | ET sur (complément de l'entier1, entier2) | 4 |
logandc2 | 0 | 0 | 1 | 0 | ET sur (entier1, complément de l'entier2) | 2 |
logorc1 | 1 | 1 | 0 | 1 | OU sur (complément de l'entier1, entier2) | -3 |
logorc2 | 1 | 0 | 1 | 1 | OU sur (entier1, complément de l'entier2) | -5 |
La dernière colonne donne les résultats des opérations sur les arguments 3 et 5 (respectivement: 0011 et 0101).
LOGBITP:
(logbitp 4 17)
T rend T car le bit de poids 2^4 contient 1 dans le nombre 10001 (17)
(logbitp 3 17)
NIL rend NIL car le bit de poids 2^3 contient 0 dans le nombre 10001
LOGTEST: (logtest x y) == (not (zerop (logand x y)))
(logtest 17 16)
T rend T car il existe un bit de même poids à 1 dans
les 2 nombres 10001 et 10000
(logtest 17 10)
NIL rend NIL car aucun bit de même poids ne se trouve à 1
à la fois dans les 2 nombres 10001 et 1010
ASH:
(ash 3 2)
12 déplace tous les bits du nombre 11 (3 en décimal égale 11 en binaire) de 2 rangs vers la gauche,
ce qui donne 1100 avec 2 bits à zéro à droite (soit 12 en décimal)
(ash 17 -3)
2 déplace tous les bits du nombre 10001 (17 en décimal) de 3 rangs vers la droite
avec disparition des 3 bits de poids faible, ce qui donne: 10 (2 en décimal)
(ash -3 2)
-12 ...111101 (-4+1) devient ...110100 (-16+4)
Remarque 2: (ash 17 -3) est le premier résultat de: (floor 17 (expt 2 3))
(floor 17 (expt 2 3))
2
1
LOGCOUNT:
(logcount 5)
2 rend le nombre de bits à 1 dans un nombre positif
(logcount -3)
1 rend le nombre de bits à 0 dans un nombre négatif
INTEGER-LENGTH:
(integer-length 7)
3 rend le nombre de bits en binaire du nombre entier positif en argument (111 ici)
c'est à dire que le nombre de bits utilisés ne peut pas être inférieur à 3
(integer-length -5)
3 un nombre négatif en binaire est mis sous la forme dite "complément à deux"
5 s'écrit 00000101 sous 8 bits. Son complément à deux est 11111010 + 1 = 11111011 (-5)
le nombre de bits pour représenter -5 ne peut pas être inférieur à
(integer-length -5) + 1 = 3+1 = 4
Pour résumer: INTEGER-LENGTH rend le nombre de bits nécessaires pour représenter un nombre entier en binaire,
mais il ne faut pas oublier le bit de signe pour les nombre négatifs.
BOOLE:
Cette fonction est appelée sous la forme: (boole opération entier1 entier2)
où opération représente une constante parmi les 16 du tableau suivant:
entier1 | 0 | 0 | 1 | 1 | |
---|---|---|---|---|---|
entier2 | 0 | 1 | 0 | 1 | opération réalisée |
boole-clr | 0 | 0 | 0 | 0 | toujours 0 |
boole-set | 1 | 1 | 1 | 1 | toujours 1 |
boole-1 | 0 | 0 | 1 | 1 | entier1 |
boole-2 | 0 | 1 | 0 | 1 | entier2 |
boole-c1 | 1 | 1 | 0 | 0 | complément de l'entier1 |
boole-c2 | 1 | 0 | 1 | 0 | complément de l'entier2 |
boole-and | 0 | 0 | 0 | 1 | ET |
boole-ior | 0 | 1 | 1 | 1 | OU inclusif |
boole-xor | 0 | 1 | 1 | 0 | OU exclusif |
boole-eqv | 1 | 0 | 0 | 1 | équivalence (NON OU-exclusif) |
boole-nand | 1 | 1 | 1 | 0 | NON-ET |
boole-nor | 1 | 0 | 0 | 0 | NON-OU |
boole-andc1 | 0 | 1 | 0 | 0 | ET sur (complément de l'entier1, entier2) |
boole-andc2 | 0 | 0 | 1 | 0 | ET sur (entier1, complément de l'entier2) |
boole-orc1 | 1 | 1 | 0 | 1 | OU sur (complément de l'entier1, entier2) |
boole-orc2 | 1 | 0 | 1 | 1 | OU sur (entier1, complément de l'entier2) |
Bientôt: "les séquences."
Aucun commentaire:
Enregistrer un commentaire