Cours 8

1/29
100%

Cours 8

Contenu

  • Hi rarchie des nombres, nombres complexes
  • D but de la programmation imp rative: affectation (setf, psetf)
  • affectation de places (valeurs gauches/valeurs droites)
  • Fonctions desctructives sur les listes: nconc, nreverse, delete
  • Valeurs multiples (values, multiple-value-bind, multiple-value-list, multiple-value-call)
  • tables de hachage (make-hash-table, gethash)

Les transparents 71--76

Listes pour repr senter des piles

Une liste est une excellente fa on de repr senter une pile. Pour obtenir le sommet de la pile, il suffit d'utiliser la fonction car, pour empiler un l ment, on utilise cons et pour d piler cdr.

Ces op rations sont sans effet de bord. Empiler un objet avec cons implique la cr ation d'une nouvelle pile mais avec un l ment de plus.

Parfois, il est souhaitable de modifier une variable contenant une pile. On obtient alors souvent des idiomes comme :

(setf \pile\ (cons obj \pile\))

(setf \pile\ (cdr \pile\)

pour empiler ou d piler une pile, ici valeur de la variable \pile\*. Les deuxmacros Common Lisp push et pop* capturent ces idiomes :

\ (defparameter \pile\* '())

\PILE\

\ (push 'a \pile\*)

(A)

\ (push 'b \pile\*)

(B A)

\ (pop \pile\*)

B

\ \pile\*

(A)

\ (pop \pile\*)

A

\ \pile\*

NIL

\*

Les deux macros push et pop sont impossibles crire sous forme de fonctions, car aucune fonction n'est capable de modifier la valeur d'une variable donn e en argument.

Nombres

Sous-sections

  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode67.html)
  • + (file:///E%3A%5C%5CIrene_Book%5C%5Cnode68.html)
  • + (file:///E%3A%5C%5CIrene_Book%5C%5Cnode69.html)
  • + (file:///E%3A%5C%5CIrene_Book%5C%5Cnode70.html)
  • + (file:///E%3A%5C%5CIrene_Book%5C%5Cnode71.html)
  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode72.html)
  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode73.html)
  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode74.html)
  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode75.html)
  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode76.html)
  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode77.html)
  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode78.html)
  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode79.html)

Les diff rents types de nombres

Common Lisp propose plusieurs types de nombres, certains similaires ceux d'autres langages, d'autres sp cifiques Common Lisp. Les nombres Common Lisp sont organis s dans une arborescence dont le sommet est number.

| |

| --- |

| ![\begin{figure}\begin{center} \input arborescence-nombres.pstex_t \end{center} \end{figure}](data:image/png;base64...) |

| Figure 6.1: Arborescence des types de nombres |

Il y a deux sous-types du type number : real et complex. Contrairement ce qui est habituel en math matique, ces deux types sont disjoints, la raison tant que la repr sentation en m moire des r els et des complexes n'est pas la m me.

Sous-sections

  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode68.html)
  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode69.html)
  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode70.html)
  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode71.html)

Entiers

Les entiers Common Lisp sont diff rents des entiers des autres langages car leur taille n'est pas limit e. Il n'y a pas de limitation concernant le nombre de bits dans la repr sentation d'un entier. La seule limitation est la taille de la m moire. Exemple :

\* (expt 1234 20)

67035243914691711794360082394262505332216263021359359696306176

\*

Le type integer est un sous-type du type rational. Il y a deux sous-types du type integer : fixnum et bignum. Les fixnums sont les entiers dont la valeur absolue est suffisamment petite pour qu'on puisse la repr senter dans un mot de l'ordinateur.

La norme exige qu'un fixnum soit repr sent sur au moins 16 bits, mais le nombre exact d pend de l'impl mentation. Il est possible de tester l'intervalle des fixnums en utilisant les deux constantes globales most-positive-fixnum et most-negative-fixnum. Exemple :

\* most-positive-fixnum

536870911

\* most-negative-fixnum

-536870912

\*

Pour d terminer le nombre de bits correspondant, il suffit de calculer le logarithme (en base 2) de ces nombres. La version de CMUCL sur la famille de processeurs Pentium donne le r sultat suivant :

\* (log (- most-negative-fixnum) 2)

29.0

\*

Le nombre de bits utilis s ici (29) peut para tre un peu trange, mais s'explique facilement par la repr sentation interne des objets Common Lisp et en particulier des fixnums.

Les bignums sont les entiers qui n cessitent plus de bits que les fixnums. La conversion entre les deux est automatique. Si le r sultat d'un calcul est un entier dont la valeur absolue est assez petite pour tre repr sent e sous forme de fixnum, le r sultat sera toujours un fixnum. Le syst me CMUCL contient deux pr dicats suppl mentaires par rapport la norme : fixnump et bignump. Ces pr dicats nous permettent de tester la repr sentation.

Common Lisp est aussi capable de manipuler des entiers repr sent s avec un nombre quelconque fix de bits. Un tel entier est appel un byte (qui ne doit donc pas tre traduit par octet). Il est par exemple possible de cr er un tableau dont le contenu est une suite d'entiers sur 21 bits. Certains de ces bytes ont souvent une rep sentation efficace, en particulier ceux de 1, 8, 16 et 32 bits.

Ratios

Les ratios forment un type de nombres qui n'existe dans pratiquement aucun autre langage. Il s'agit du type ratio qui est un sous-type de rational.

Les ratios permettent de repr senter le r sultat d'un grand nombre de calculs de fa on exacte. Ce sont des calculs dont les donn es initiales sont des rationnels (en particulier des entiers) et dont les op rations sont uniquement addition, soustraction, multiplication et division.

Un exemple de ce type de calcul est la r solution de syst mes d' quations lin aires coefficients rationnels. Ce type de calcul n cessite parfois la soustraction entre deux nombres de diff rents ordres de grandeur. Si les flottants sont utilis s pour effectuer un tel calcul, on risque de perdre une grande partie de la pr cision dans les calculs interm diaires, ce qui peut donner un r sultat final erron et donc inexploitable

Flottants

Le type float est un sous-type de real mais n'est pas un sous-type de rational, m me si les flottants forment en fait un sous-ensemble des rationnels. Les deux types float et rational sont en fait distincts.

Comme indiqu dans la section [4.1.1](file:///E%3A%5CIrene_Book%5Cnode45.html#exprflottants), il y a quatre sous-types du type float : short-float, single-float, double-float et long-float.

Les op rations dont le r sultat est un flottant (fonctions trigonim triques, logarithmes, etc) doivent choisir le sous-type exact de float parmi ceux disponibles. La r gle Common Lisp est simple : le type exact du r sultat est le m me que le type le plus pr cis des arguments. Exemple :

\* (expt 2.4 4.5)

51.398525

\* (expt 2.4d0 4.5)

51.39851690685247d0

\* (expt 2.4 4.5d0)

51.39852609762414d0

\*

Complexes

Le type complex est un sous-type du type number. Comme cela a d j t indiqu dans la section [4.1.1](file:///E%3A%5CIrene_Book%5Cnode46.html#exprcomplexes), il y a deux sous-types du type complex selon le type des composants. En Common Lisp, ces deux types s'appellent (complex rational) et (complex float). On remarque que les noms de ces deux types ne sont pas des symboles, mais des listes dont le premier l ment est complex et le deuxi me le nom d'un sous-type de real. En fait, le type complex est param trable avec un type r el qui indique le type des deux parties. Un type dont le nom est un symbole est appel type atomique (en Anglais : atomic type) et un type dont le nom est param tr est appel type composite (en Anglais : compound type).

Pr dicats

Common Lisp tant un langage dynamiquement typ , il est souvent n cessaire de tester le type d'un objet. Ceci se fait gr ce des pr dicats de type. Un pr dicat est une fonction dont la valeur de retour est bool enne. Voici les pr dicats de type qui s'appliquent aux nombres :

| | |

| --- | --- |

| nom | fonction |

| numberp | pour tester si un objet est un nombre |

| realp | pour tester si un objet est un nombre r el |

| complexp | pour tester si un objet est un nombre complexe |

| rationalp | pour tester si un objet est rationnel |

| integerp | pour tester si un objet est un entier |

| floatp | pour tester si un objet est un flottant |

| zerop | pour tester si un nombre est gal 0 |

| plusp | pour tester si un nombre est positif |

| minusp | pour tester si un nombre est n gatif |

| evenp | pour tester si un entier est pair |

| oddp | pour tester si un entier est impair |

Chacun des pr dicats numberp, realp, complexp, rationalp, integerp et floatp s'applique un objet Common Lisp arbitraire, alors que zerop, plusp et minusp n cessitent un nombre et evenp et oddp un entier.

Publicité

Comparaisons

Les nombres r els sont totalement ordonn s. Les op rations de comparaison permettent de tester l'ordre entre deux ou plusieurs nombres. Les nombres complexes ne sont pas totalement ordonn s, mais les tests d' galit et in galit existent.

Voici les op rations de comparaison en Common Lisp :

| | |

| --- | --- |

| nom | fonction |

| = | gal |

| /= | in gal |

| < | inf rieur |

| <= | inf rieur ou gal |

| > | sup rieur |

| >= | sup rieur ou gal |

Contrairement d'autres langages qui exigent exactement deux op randes pour ces op rations, Common Lisp g n ralise ces op rations un nombre arbitraire (sup rieur z ro) d'op randes.

Voici la d finition de ces op rations :

| | |

| --- | --- |

| nom | fonction |

| = | vrai si et seulement si tous les op randes sont gaux |

| /= | vrai si et seulement si tous les op randes sont diff rents |

| < | vrai si et seulement si les op randes sont strictement croissants |

| <= | vrai si et seulement si les op randes sont croissants |

| > | vrai si et seulement si les op randes sont strictement d croissants |

| >= | vrai si et seulement si les op randes sont d croissants |

Par d finition, l'ensemble de ces op rations donne vrai si un seul argument a t fourni. Exemples :

\* (= 1.0)

T

\* (= 1.0 1)

T

\* (= 1.0 2.0)

NIL

\* (= 4/2 2 #c(2.0 0))

T

\* (< 1/3 0.5 3/2 1.04)

NIL

\* (< 1/3 0.5 3/2 1.9)

T

\* (> 12 14/2 7 1/5 0.002)

NIL

\* (> 12 15/2 7 1/5 0.002)

T

\* (> 12 14/2 7 1/5 0.002)

NIL

\* (>= 12 14/2 7 1/5 0.002)

T

\*

Alors que d'autres langages traitent les op rateurs de comparaison comme l ments syntaxiques sp ciaux, en Common Lisp il s'agit de fonctions normales dont les noms sont les symboles =, /=, <, <=, > et >=. Ceci est important, car il devient alors possible de passer l'une de ces fonctions en argument d'autres fonctions (voir chapitre [7](file:///E%3A%5CIrene_Book%5Cnode87.html#chapfonctions)).

Op rations arithm tiques simples

Comme d'autres langages, Common Lisp a des op rations d'addition, soustraction, mulitplication et division. Mais comme pour les op rations de comparaison, il s'agit en Common Lisp de fonctions normales dont les noms sont les symboles suivants :

| | |

| --- | --- |

| nom | fonction |

| + | addition |

| - | soustraction |

| \* | multiplication |

| / | division |

La fonction d'addition prend un nombre arbitraire de param tres. Elle renvoie la somme des arguments, ou 0 si aucun argument n'a t fourni. Les arguments peuvent tre de sous-type arbitraire du type number, y compris complex. Exemples :

\* (+)

0

\* (+ 123)

123

\* (+ 12 #c(3.1 9))

#C(15.1 9.0)

\* (+ 12 #c(3.1 9d0))

#C(15.099999904632568d0 9.0d0)

\* (+ 1 2 3 4 5 6 7 8 9 10)

55

\*

La fonction de soustraction prend au moins un argument. Si un seul argument est fourni, cette fonction renvoie l'oppos de celui-ci. Si le nombre d'arguments fournis est sup rieur un, alors la fonction de soustraction renvoie la diff rence entre le premier et la somme des autres. Exemples :

\* (- 234)

-234

\* (- #c(2345 22/3))

#C(-2345 -22/3)

\* (- 33 2 5 3 4 1.4)

17.6

\* (- 33 2 5 3 4 1.4d2)

-121.0d0

\* (- 33 2 5 3 4 1.4d1)

5.0d0

\* (- 33 2 5 3 4 1.41d1)

4.9d0

\*

Comme l'addition, la fonction de multiplication prend un nombre arbitraire d'arguments. Elle renvoie le produit des arguments, ou 1 si aucun argument n'a t fourni. Exemples :

\ (\)

1

\ (\ 123/11)

123/11

\ (\ 123/11 12.33)

137.87181

\ (\ 123/11 12.33 #c(33 11))

#C(4549.7695 1516.59)

\*

Comme la soustraction, la fonction de divison prend au moins un argument. Si un seul argument est fourni, cette fonction renvoie l'inverse de celui-ci. Si le nombre d'arguments fournis est sup rieur un, alors elle renvoie le premier argument divis par le produit des autres. Exemples :

\* (/ 2345)

1/2345

\* (/ #c(22 4.8))

#C(0.04338908 -0.009466709)

\* (/ 12 3.0)

4.0

\* (/ 112 2 8.0 2d1)

0.35d0

\*

Les fonctions max et min prennent au moins un argument. Les arguments doivent tre de type real. Exemples :

\* (max 4)

4

\* (max 9 46/5 9.01)

46/5

\* (min 9 46/5 9.01)

Publicité

9

\*

Trigonom trie

Common Lisp propose une gamme compl te de fonctions trigonom triques :

| | |

| --- | --- |

| nom | fonction |

| sin | sinus de l'argument en radians |

| cos | cosinus de l'argument en radians |

| tan | tangent de l'argument en radians |

Ces fonctions sont similaires leurs homologues d'autres langages de programmation, la diff rence principale tant que les fonctions Common Lisp donnent aussi un r sultat si l'argument est un nombre complexe et que la pr cision du r sultat d pend de la pr cision de l'argument. Exemples :

\* (sin 1)

0.84147096

\* (sin 1.0)

0.84147096

\* (sin 0.1d1)

0.8414709848078965d0

\* (sin #c(1.0 2.0))

#C(3.1657784 1.9596009)

\* pi

3.141592653589793d0

\* (cos pi)

-1.0d0

\* (tan (/ pi 4))

0.9999999999999999d0

\*

Voici les fonctions trigonom triques inverses propos es par Common Lisp :

| | |

| --- | --- |

| nom | fonction |

| asin | inverse de sinus |

| acos | inverse de cosinus |

| atan | inverse de tangent |

Ces fonctions asin et acos renvoient un r sultat complexe si la valeur absolue de l'argument est sup rieure 1 ou si l'argument est complexe. La fonction atan renvoie un r sultat complexe si l'argument est complexe :

\* (asin 0.44)

0.45559868

\* (asin 1.0)

1.5707964

\* (asin 1.1)

#C(1.5707964 -0.4435683)

\* (acos -34)

#C(3.1415927 -4.219291)

\* (acos -34d0)

#C(3.141592653589793d0 -4.219291372012082d0)

\* (atan 2320934029384029384029384023984502938)

1.5707964

\* (atan #c(1.0 2.0))

#C(1.3389726 0.4023595)

\*

Trigonom trie hyperbolique

Les fonctions trigonom triques hyperboliques suivantes existent :

| | | |

| --- | --- | --- |

| nom | fonction | d finition |

| sinh | sinus hyperbolique | ![$\frac{e^x - e^{-x}}{2}$](data:image/png;base64...) |

| cosh | cosinus hyperbolique | ![$\frac{e^x + e^{-x}}{2}$](data:image/png;base64...) |

| tanh | tangent hyperbolique | ![$\frac{e^x - e^{-x}}{e^x + e^{-x}}$](data:image/png;base64...) |

| asinh | sinus hyperbolique inverse | ![$\texttt{log}(x+\sqrt{1+x^2})$](data:image/png;base64...) |

| acosh | cosinus hyperbolique inverse | ![$2\texttt{log}(\sqrt{\frac{x+1}{2}} + \sqrt{\frac{x-1}{2}})$](data:image/png;base64...) |

| atanh | tangent hyperbolique inverse | ![$\frac{\texttt{log}(1+x) - \texttt{log}(1-x)}{2}$](data:image/png;base64...) |

Logarithmes et exponentielles

Les fonctions logarithmiques et exponentielles existent :

| | |

| --- | --- |

| nom | fonction |

| log | logarithme |

| exp | exponentielle naturelle |

| expt | exponentielle d'une base arbitraire |

La fonction log calcule le logarithme n p rien, mais accepte aussi un deuxi me argument facultatif indiquant la base. Exemples :

\* (exp 1)

2.7182817

\* (exp -1)

0.36787945

\ (exp (\ #c(0 1) pi))

#C(-1.0d0 1.2246063538223773d-16)

\* (expt 2 30)

1073741824

\* (log 3)

1.0986123

\* (log (expt 10 9) 2)

29.897354

\*

Op rations bit bit

Les entiers Common Lisp sont cod s en utilisant la rep sentation binaire en compl ment 2. On peut voir un entier comme une suite infinie de bits. Si le nombre est positif, le nombre est pr c d d'une suite infinie de bits 0 et s'il est n gatif, d'une suite infinie de bits 1. Voici les fonctions qui exploitent cette repr sentation :

| | |

| --- | --- |

| nom | fonction |

| logand | et entre les arguments |

| logandc1 | et entre compl ment du premier et deuxi me argument |

| loganc2 | et entre premier argument et compl ment du deuxi me |

| logeql | quivalence entre les arguments |

| logior | ou inclusif entre les deux arguments |

| lognand | compl ment du et entre les arguments |

| lognor | compl ment du ou inclusif entre les arguments |

| lognot | compl ment de l'argument |

| logorc1 | ou inclusif entre compl ment du premier et deuxi me argument |

| logorc2 | ou inclusif entre premier argument et compl ment du deuxi me |

| logxor | ou exclusif entre les arguments |

| logbitp | vrai si un bit est 1 dans l'argument |

| logcount | nombre de bits 1 ou 0 dans l'argument |

| logtest | vrai si des bits sont 1 |

Conversion, troncature, arrondi

Plusieurs fonctions existent pour la troncature et l'arrondi. Ces fonctions prennent toutes deux arguments : un nombre ![$n$](data:image/png;base64...)et un diviseur ![$d$](data:image/png;base64...). Le diviseur est facultatif et sa valeur par d faut est 1. Chacune de ces fonctions renvoie deux valeurs (voir chapitre [13](file:///E%3A%5CIrene_Book%5Cnode158.html#chapmultiplevalues)), un quotient ![$q$](data:image/png;base64...)et un reste ![$r$](data:image/png;base64...)tels que ![$qd + r = n$](data:image/png;base64...). La valeur ![$q$](data:image/png;base64...)est obtenue par une division entre ![$n$](data:image/png;base64...)et ![$d$](data:image/png;base64...), suivie d'une conversion du r sultat en entier. La diff rence entre ces fonctions r side dans la fa on dont est faite cette conversion. Voici les fonctions disponibles :

| | |

| --- | --- |

| nom | fonction |

| floor | r sultat tronqu vers l'infini n gatif |

Publicité

| ceiling | r sultat tronqu vers l'infini positif |

| truncate | r sultat tronqu vers z ro |

| round | r sultat arrondi vers l'entier le plus proche |

Exemples :

\* (floor 234/11 5.4)

3

5.072727

\* (floor -234/11 5.4)

-4

0.3272729

\* (ceiling 234/11 5.4)

4

-0.3272729

\* (ceiling -234/11 5.4)

-3

-5.072727

\* (truncate 234/11 5.4)

3

5.072727

\* (truncate -234/11 5.4)

-3

-5.072727

\* (round 234/11 5.4)

4

-0.3272729

\* (round -234/11 5.4)

-4

0.3272729

\* (floor 233/3)

77

2/3

\* (round 234.444)

234

0.44400024

\*

Les fonctions ffloor, fceiling, ftruncate et fround sont similaires aux fonctions ci-dessus, la seule diff rence que la valeur ![$q$](data:image/png;base64...)est un flottant au lieu d'un entier :

\* (ffloor 23 5)

4.0

3

\* (fround -234/33 2/5)

-18.0

6/55

\* (fceiling 44.234d0 3)

15.0d0

-0.7659999999999982d0

\* (ftruncate 9384593847593847593857938475938579385 3)

3.1281978e+36

1

\*

Pour convertir un nombre rationnel en flottant, ou un flottant en complexe, utiliser coerce :

\* (coerce 234 'float)

234.0

\* (coerce 234 'double-float)

234.0d0

\* (coerce 234/5 'double-float)

46.8d0

\* (coerce 2.234 'complex)

#C(2.234 0.0)

\*

Symboles

Sous-sections

  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode81.html)
  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode82.html)
  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode83.html)
  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode84.html)

Pr dicats sur les symboles

Les symboles repr sentent un type de donn e unique en Common Lisp. Une caract ristique essentielle des symboles est qu'ils sont uniques, savoir deux suites de caract res identiques dans le m me programme (et dans le m me paquetage), repr sentent le m me symbole. Ceci n'est pas vrai pour les cha nes de caract res, par exemple. Pour les symboles, c'est une qualit essentielle, car en Common Lisp, ils sont utilis s pour nommer des variables et le programmeur est habitu ce que deux occurrences du m me nom de variable r f rencent la m me variable.

Pour tester si un objet Common Lisp est un symbole, utiliser le pr dicat symbolp :

\ \print-level\*

NIL

\ (symbolp \print-level\*)

T

\ \standard-output\*

#<Synonym Stream to SYSTEM:\STDOUT\>

\ (symbolp \standard-output\*)

NIL

\ (symbolp '\standard-output\*)

T

\*

Variables lexicales et sp ciales

Il y a deux types de variables en Common Lisp : variables lexicales et variables sp ciales (ou dynamiques) (en Anglais : lexical variables et special variables) . Les variables lexicales en Common Lisp sont similaires aux variables d'autres langages de programmation. Une telle variable peut tre cr e par un let. Les param tres d'une fonction sont des variables lexicales. Pour des raisons d'efficacit , il n'est pas possible de manipuler la liaison entre un symbole repr sentant une variable lexicale et sa valeur. Les seules op rations permises sont la r cup ration et l'affectation de la valeur. Pour ces deux op rations, le nom de la variable est connu par le compilateur ce qui permet ce dernier de g n rer du code efficace. La port e d'une variable lexicale est limit e une partie du programme d termin e seulement par son texte. Exemple :

\* (let ((x 10))

(defun f (y)

(+ x y)))

F

\* (defun g (x)

(f x))

G

\* (g 3)

13

\*

Ici, il y a deux variables diff rentes dont le nom est x : la premi re est cr e par le let et r f renc e dans f et la deuxi me est cr e implicitement quand g est invoqu e et r f renc e dans le corps de g.

Les variables sp ciales, par contre, sont tr s diff rentes des variables lexicales. La port e d'une variable sp ciale n'est pas limit e au texte du programme. Une telle variable est cr e par defparameter (entre autres). Voici le m me exemple avec une variable sp ciale :

\* (defparameter x 5)

X

\* (let ((x 10))

(defun f (y)

(+ x y)))

F

\* (defun g (x)

(f x))

G

\* (g 3)

6

\* x

5

\*

Publicité

Ici, il y a une seule variable x. Elle est sp ciale car elle est cr e par defparameter. Lorsque f est d finie, cette variable aura la valeur 10 comme dans l'exemple pr c dent. Mais l'appel de g avec l'argument 3 modifie la valeur de la variable x pour la dur e de l'ex cution de g, m me pendant l'appel f.

Les variables sp ciales se comportent d'une fa on tellement diff rente des variable lexicales que les programmeurs Common Lisp ont d cid d'avertir un lecteur ventuel du programme de la pr sence d'une variable sp ciale : la convention est d'entourer le nom d'une variable sp ciale par des ast risques comme pour \print-level\ ou \read-base\.

L'utilisation de variables sp ciales est une technique de programmation importante en Common Lisp. L'utilisation la plus fr quente est d' viter le passage d'un argument une fonction dont la valeur est presque toujours la m me, mais cependant susceptible de changer. Un exemple classique de ce type d'utilisation est illustr par les variables \read-base\ et \print-base\. Celles-ci d terminent la base utiliser pour lire et afficher les nombres. Cette base est presque toujours 10, mais il peut arriver qu'on ait besoin de la changer. Sans variable sp ciale, on a deux possibilit s pour changer le comportement des fonctions de lecture et d'affichage. La premi re est d'utiliser une variable globale comme ceci :

\ \print-base\*

10

\* (print 11)

11

11

\ (setf \print-base\* 8)

10

\* (print 11)

13

13

\ (setf \print-base\* 10)

10

\* (print 11)

11

11

\*

Dans cette exemple, \print-base\* est affect e 8 pour la dur e d'un calcul (ici le calcul trivial 11), puis nouveau affect e 10*. C'est une m thode peu pratique, en particulier si le calcul risque de provoquer une erreur, auquel cas la deuxi me affectation ne sera pas effectu e ( moins de compliquer le code).

Dans l'exemple ci-dessus, on remarque que l' valuation de l'appel print donne deux lignes d'affichage de la part du syst me : la premi re est l'effet de bord de print dont le r sultat est d'afficher la valeur et la deuxi me est la valeur de l'expression (print 11), en l'occurrence la m me que l'argument donn print.

La deuxi me possibilit est d' crire les fonctions de lecture et d'affichage avec un param tre suppl mentaire indiquant la valeur de la base ; ceci introduit beaucoup de code suppl mentaire, souvent le m me chaque fois.

Avec les variables sp ciales, il est possible de changer temporairement une valeur pendant la dur e d'un calcul, sans crainte d'erreur :

\ \print-base\*

10

\* (print 11)

11

11

\ (let ((\print-base\* 8)) (print 11))

13

11

\ \print-base\*

10

\* (print 11)

11

11

\*

Dans cette exemple, on remarque les lignes :

\ (let ((\print-base\* 8)) (print 11))

13

11

La valeur de la variable sp ciale \print-base\ est 8 pendant l'ex cution de la fonction print. La premi re ligne d'affichage donne donc 13. La deuxi me ligne d'affichage (11) repr sente la valeur de l'expression (let ((\print-base\ 8)) (print 11)) enti re. Cette valeur est 11 et lorsque cette valeur est affich e, la valeur de \print-base\ est redevenue 10. Ici, m me si le corps du let provoque une erreur, la valeur de \print-base\* redeviendra 10*.

Pour les variables sp ciales, il est possible de manipuler explicitement la correspondance entre symboles et valeurs. La fonction symbol-value permet d'acc der la valeur d'un symbole et de la changer avec setf :

\ (symbol-value '\print-base\*)

10

\ (setf (symbol-value '\print-base\*) 8)

10

\* 11

13

\ (defparameter \sym\ '\print-base\*)

\SYM\

\ \sym\*

\PRINT-BASE\

\ (symbol-value \sym\*)

10

\ (setf (symbol-value \sym\*) 10)

10

\* 11

11

\*

mots-cl s

Un symbole dont le nom commence par :' est un mot-cl (en Anglais : keyword). Techniquement, le caract re :' ne fait pas partie du nom, mais indique le paquetage (en Anglais : package) dans lequel est contenu le symbole.

Pour tester si un symbole est un mot-cl , utiliser le pr dicat keywordp :

\* (keywordp ':bonjour)

T

\* (keywordp 'bonjour)

NIL

\*

Les mots-cl s sont particuliers pour plusieurs raisons. D'abord, la valeur d'un mot-cl est ce m me mot-cl :

\* :ab

:AB

\* :lskdfjlskdjflskdjf

:LSKDFJLSKDJFLSKDJF

\*

Les mots-cl s permettent de nommer des param tres d'une fonction. C'est leur utilisation principale. Certaines fonctions ont besoin d'un grand nombre de param tres, dont la majorit ne change pas d'une invocation l'autre. Un exemple typique est une fonction de cr ation d'une fen tre dans un syst me de fen trage comme X11. Les param tres d'une telle fonction d terminent la position et les dimensions de la fen tre, la couleur du fond, la profondeur, la fen tre m re, le masque d' v nements, etc.

Dans un langage de programmation sans param tres nomm s, un appel de ce type de fonction est difficile lire et comprendre, car il faut se souvenir de la signification de chaque param tre, puis v rifier la position de chacun. Les param tres nomm s permettent de simplifier consid rablement ce type d'appel. Exemple (de la biblioth que CLX pour le syst me X11) :

(create-window :parent root

:x 10 :y 20

:width 200 :height 300)

Ici un mot-cl est utilis pour nommer l'argument qui suit. L'ordre n'a pas d'importance. L'appel suivant est donc identique au pr c dent :

(create-window :y 20 :x 10

:width 200 :height 300

:parent root)

Autres utilisations des symboles

Les symboles ne sont pas utilis s uniquement pour la repr sentation des variables. chaque symbole est associ e une liste de propri t s (en Anglais : property list) que l'on peut utiliser pour fabriquer une base de donn es simple. La liste des propri t s d'un symbole est une liste dans laquelle un l ment sur deux est un indicateur et un l ment sur deux est une valeur. Les deux sont des objets Common Lisp arbitraires. La fonction get prend deux param tres, un symbole et un indicateur et renvoie la valeur correspondant l'indicateur, ou nil si l'indicateur n'existe pas pour le symbole. Avec setf, il est possible de changer ou cr er la valeur associ e un indicateur. Exemples :

\* (get 'jane 'mother)

NIL

\* (setf (get 'jane 'mother) 'anne)

ANNE

\* (get 'jane 'mother)

ANNE

\* (setf (get 'anne 'profession) 'carpenter)

CARPENTER

\* (get (get 'jane 'mother) 'profession)

CARPENTER

\*

Caract res

=caracteres.tex

;''

Cha nes de caract res

=chaines.tex

;''

Cours 8

Programming, Mathematics, Common Lisp · course

Voir tous les documents en programmation

Cours 8

Contenu

  • Hi rarchie des nombres, nombres complexes
  • D but de la programmation imp rative: affectation (setf, psetf)
  • affectation de places (valeurs gauches/valeurs droites)
  • Fonctions desctructives sur les listes: nconc, nreverse, delete
  • Valeurs multiples (values, multiple-value-bind, multiple-value-list, multiple-value-call)
  • tables de hachage (make-hash-table, gethash)

Les transparents 71--76

Listes pour repr senter des piles

Une liste est une excellente fa on de repr senter une pile. Pour obtenir le sommet de la pile, il suffit d'utiliser la fonction car, pour empiler un l ment, on utilise cons et pour d piler cdr.

Ces op rations sont sans effet de bord. Empiler un objet avec cons implique la cr ation d'une nouvelle pile mais avec un l ment de plus.

Parfois, il est souhaitable de modifier une variable contenant une pile. On obtient alors souvent des idiomes comme :

(setf \pile\ (cons obj \pile\))

(setf \pile\ (cdr \pile\)

pour empiler ou d piler une pile, ici valeur de la variable \pile\*. Les deuxmacros Common Lisp push et pop* capturent ces idiomes :

\ (defparameter \pile\* '())

\PILE\

\ (push 'a \pile\*)

(A)

\ (push 'b \pile\*)

(B A)

\ (pop \pile\*)

B

\ \pile\*

(A)

\ (pop \pile\*)

A

\ \pile\*

NIL

\*

Les deux macros push et pop sont impossibles crire sous forme de fonctions, car aucune fonction n'est capable de modifier la valeur d'une variable donn e en argument.

Nombres

Sous-sections

  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode67.html)
  • + (file:///E%3A%5C%5CIrene_Book%5C%5Cnode68.html)
  • + (file:///E%3A%5C%5CIrene_Book%5C%5Cnode69.html)
  • + (file:///E%3A%5C%5CIrene_Book%5C%5Cnode70.html)
  • + (file:///E%3A%5C%5CIrene_Book%5C%5Cnode71.html)
  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode72.html)
  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode73.html)
  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode74.html)
  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode75.html)
  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode76.html)
  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode77.html)
  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode78.html)
  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode79.html)

Les diff rents types de nombres

Common Lisp propose plusieurs types de nombres, certains similaires ceux d'autres langages, d'autres sp cifiques Common Lisp. Les nombres Common Lisp sont organis s dans une arborescence dont le sommet est number.

| |

| --- |

| ![\begin{figure}\begin{center} \input arborescence-nombres.pstex_t \end{center} \end{figure}](data:image/png;base64...) |

| Figure 6.1: Arborescence des types de nombres |

Il y a deux sous-types du type number : real et complex. Contrairement ce qui est habituel en math matique, ces deux types sont disjoints, la raison tant que la repr sentation en m moire des r els et des complexes n'est pas la m me.

Sous-sections

  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode68.html)
  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode69.html)
  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode70.html)
  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode71.html)

Entiers

Les entiers Common Lisp sont diff rents des entiers des autres langages car leur taille n'est pas limit e. Il n'y a pas de limitation concernant le nombre de bits dans la repr sentation d'un entier. La seule limitation est la taille de la m moire. Exemple :

\* (expt 1234 20)

67035243914691711794360082394262505332216263021359359696306176

\*

Le type integer est un sous-type du type rational. Il y a deux sous-types du type integer : fixnum et bignum. Les fixnums sont les entiers dont la valeur absolue est suffisamment petite pour qu'on puisse la repr senter dans un mot de l'ordinateur.

La norme exige qu'un fixnum soit repr sent sur au moins 16 bits, mais le nombre exact d pend de l'impl mentation. Il est possible de tester l'intervalle des fixnums en utilisant les deux constantes globales most-positive-fixnum et most-negative-fixnum. Exemple :

\* most-positive-fixnum

536870911

\* most-negative-fixnum

-536870912

\*

Pour d terminer le nombre de bits correspondant, il suffit de calculer le logarithme (en base 2) de ces nombres. La version de CMUCL sur la famille de processeurs Pentium donne le r sultat suivant :

\* (log (- most-negative-fixnum) 2)

29.0

\*

Le nombre de bits utilis s ici (29) peut para tre un peu trange, mais s'explique facilement par la repr sentation interne des objets Common Lisp et en particulier des fixnums.

Les bignums sont les entiers qui n cessitent plus de bits que les fixnums. La conversion entre les deux est automatique. Si le r sultat d'un calcul est un entier dont la valeur absolue est assez petite pour tre repr sent e sous forme de fixnum, le r sultat sera toujours un fixnum. Le syst me CMUCL contient deux pr dicats suppl mentaires par rapport la norme : fixnump et bignump. Ces pr dicats nous permettent de tester la repr sentation.

Common Lisp est aussi capable de manipuler des entiers repr sent s avec un nombre quelconque fix de bits. Un tel entier est appel un byte (qui ne doit donc pas tre traduit par octet). Il est par exemple possible de cr er un tableau dont le contenu est une suite d'entiers sur 21 bits. Certains de ces bytes ont souvent une rep sentation efficace, en particulier ceux de 1, 8, 16 et 32 bits.

Ratios

Les ratios forment un type de nombres qui n'existe dans pratiquement aucun autre langage. Il s'agit du type ratio qui est un sous-type de rational.

Les ratios permettent de repr senter le r sultat d'un grand nombre de calculs de fa on exacte. Ce sont des calculs dont les donn es initiales sont des rationnels (en particulier des entiers) et dont les op rations sont uniquement addition, soustraction, multiplication et division.

Un exemple de ce type de calcul est la r solution de syst mes d' quations lin aires coefficients rationnels. Ce type de calcul n cessite parfois la soustraction entre deux nombres de diff rents ordres de grandeur. Si les flottants sont utilis s pour effectuer un tel calcul, on risque de perdre une grande partie de la pr cision dans les calculs interm diaires, ce qui peut donner un r sultat final erron et donc inexploitable

Flottants

Le type float est un sous-type de real mais n'est pas un sous-type de rational, m me si les flottants forment en fait un sous-ensemble des rationnels. Les deux types float et rational sont en fait distincts.

Comme indiqu dans la section [4.1.1](file:///E%3A%5CIrene_Book%5Cnode45.html#exprflottants), il y a quatre sous-types du type float : short-float, single-float, double-float et long-float.

Les op rations dont le r sultat est un flottant (fonctions trigonim triques, logarithmes, etc) doivent choisir le sous-type exact de float parmi ceux disponibles. La r gle Common Lisp est simple : le type exact du r sultat est le m me que le type le plus pr cis des arguments. Exemple :

\* (expt 2.4 4.5)

51.398525

\* (expt 2.4d0 4.5)

51.39851690685247d0

\* (expt 2.4 4.5d0)

51.39852609762414d0

\*

Complexes

Le type complex est un sous-type du type number. Comme cela a d j t indiqu dans la section [4.1.1](file:///E%3A%5CIrene_Book%5Cnode46.html#exprcomplexes), il y a deux sous-types du type complex selon le type des composants. En Common Lisp, ces deux types s'appellent (complex rational) et (complex float). On remarque que les noms de ces deux types ne sont pas des symboles, mais des listes dont le premier l ment est complex et le deuxi me le nom d'un sous-type de real. En fait, le type complex est param trable avec un type r el qui indique le type des deux parties. Un type dont le nom est un symbole est appel type atomique (en Anglais : atomic type) et un type dont le nom est param tr est appel type composite (en Anglais : compound type).

Pr dicats

Common Lisp tant un langage dynamiquement typ , il est souvent n cessaire de tester le type d'un objet. Ceci se fait gr ce des pr dicats de type. Un pr dicat est une fonction dont la valeur de retour est bool enne. Voici les pr dicats de type qui s'appliquent aux nombres :

| | |

| --- | --- |

| nom | fonction |

| numberp | pour tester si un objet est un nombre |

| realp | pour tester si un objet est un nombre r el |

| complexp | pour tester si un objet est un nombre complexe |

| rationalp | pour tester si un objet est rationnel |

| integerp | pour tester si un objet est un entier |

| floatp | pour tester si un objet est un flottant |

| zerop | pour tester si un nombre est gal 0 |

| plusp | pour tester si un nombre est positif |

| minusp | pour tester si un nombre est n gatif |

| evenp | pour tester si un entier est pair |

| oddp | pour tester si un entier est impair |

Chacun des pr dicats numberp, realp, complexp, rationalp, integerp et floatp s'applique un objet Common Lisp arbitraire, alors que zerop, plusp et minusp n cessitent un nombre et evenp et oddp un entier.

Publicité

Comparaisons

Les nombres r els sont totalement ordonn s. Les op rations de comparaison permettent de tester l'ordre entre deux ou plusieurs nombres. Les nombres complexes ne sont pas totalement ordonn s, mais les tests d' galit et in galit existent.

Voici les op rations de comparaison en Common Lisp :

| | |

| --- | --- |

| nom | fonction |

| = | gal |

| /= | in gal |

| < | inf rieur |

| <= | inf rieur ou gal |

| > | sup rieur |

| >= | sup rieur ou gal |

Contrairement d'autres langages qui exigent exactement deux op randes pour ces op rations, Common Lisp g n ralise ces op rations un nombre arbitraire (sup rieur z ro) d'op randes.

Voici la d finition de ces op rations :

| | |

| --- | --- |

| nom | fonction |

| = | vrai si et seulement si tous les op randes sont gaux |

| /= | vrai si et seulement si tous les op randes sont diff rents |

| < | vrai si et seulement si les op randes sont strictement croissants |

| <= | vrai si et seulement si les op randes sont croissants |

| > | vrai si et seulement si les op randes sont strictement d croissants |

| >= | vrai si et seulement si les op randes sont d croissants |

Par d finition, l'ensemble de ces op rations donne vrai si un seul argument a t fourni. Exemples :

\* (= 1.0)

T

\* (= 1.0 1)

T

\* (= 1.0 2.0)

NIL

\* (= 4/2 2 #c(2.0 0))

T

\* (< 1/3 0.5 3/2 1.04)

NIL

\* (< 1/3 0.5 3/2 1.9)

T

\* (> 12 14/2 7 1/5 0.002)

NIL

\* (> 12 15/2 7 1/5 0.002)

T

\* (> 12 14/2 7 1/5 0.002)

NIL

\* (>= 12 14/2 7 1/5 0.002)

T

\*

Alors que d'autres langages traitent les op rateurs de comparaison comme l ments syntaxiques sp ciaux, en Common Lisp il s'agit de fonctions normales dont les noms sont les symboles =, /=, <, <=, > et >=. Ceci est important, car il devient alors possible de passer l'une de ces fonctions en argument d'autres fonctions (voir chapitre [7](file:///E%3A%5CIrene_Book%5Cnode87.html#chapfonctions)).

Op rations arithm tiques simples

Comme d'autres langages, Common Lisp a des op rations d'addition, soustraction, mulitplication et division. Mais comme pour les op rations de comparaison, il s'agit en Common Lisp de fonctions normales dont les noms sont les symboles suivants :

| | |

| --- | --- |

| nom | fonction |

| + | addition |

| - | soustraction |

| \* | multiplication |

| / | division |

La fonction d'addition prend un nombre arbitraire de param tres. Elle renvoie la somme des arguments, ou 0 si aucun argument n'a t fourni. Les arguments peuvent tre de sous-type arbitraire du type number, y compris complex. Exemples :

\* (+)

0

\* (+ 123)

123

\* (+ 12 #c(3.1 9))

#C(15.1 9.0)

\* (+ 12 #c(3.1 9d0))

#C(15.099999904632568d0 9.0d0)

\* (+ 1 2 3 4 5 6 7 8 9 10)

55

\*

La fonction de soustraction prend au moins un argument. Si un seul argument est fourni, cette fonction renvoie l'oppos de celui-ci. Si le nombre d'arguments fournis est sup rieur un, alors la fonction de soustraction renvoie la diff rence entre le premier et la somme des autres. Exemples :

\* (- 234)

-234

\* (- #c(2345 22/3))

#C(-2345 -22/3)

\* (- 33 2 5 3 4 1.4)

17.6

\* (- 33 2 5 3 4 1.4d2)

-121.0d0

\* (- 33 2 5 3 4 1.4d1)

5.0d0

\* (- 33 2 5 3 4 1.41d1)

4.9d0

\*

Comme l'addition, la fonction de multiplication prend un nombre arbitraire d'arguments. Elle renvoie le produit des arguments, ou 1 si aucun argument n'a t fourni. Exemples :

\ (\)

1

\ (\ 123/11)

123/11

\ (\ 123/11 12.33)

137.87181

\ (\ 123/11 12.33 #c(33 11))

#C(4549.7695 1516.59)

\*

Comme la soustraction, la fonction de divison prend au moins un argument. Si un seul argument est fourni, cette fonction renvoie l'inverse de celui-ci. Si le nombre d'arguments fournis est sup rieur un, alors elle renvoie le premier argument divis par le produit des autres. Exemples :

\* (/ 2345)

1/2345

\* (/ #c(22 4.8))

#C(0.04338908 -0.009466709)

\* (/ 12 3.0)

4.0

\* (/ 112 2 8.0 2d1)

0.35d0

\*

Les fonctions max et min prennent au moins un argument. Les arguments doivent tre de type real. Exemples :

\* (max 4)

4

\* (max 9 46/5 9.01)

46/5

\* (min 9 46/5 9.01)

Publicité

9

\*

Trigonom trie

Common Lisp propose une gamme compl te de fonctions trigonom triques :

| | |

| --- | --- |

| nom | fonction |

| sin | sinus de l'argument en radians |

| cos | cosinus de l'argument en radians |

| tan | tangent de l'argument en radians |

Ces fonctions sont similaires leurs homologues d'autres langages de programmation, la diff rence principale tant que les fonctions Common Lisp donnent aussi un r sultat si l'argument est un nombre complexe et que la pr cision du r sultat d pend de la pr cision de l'argument. Exemples :

\* (sin 1)

0.84147096

\* (sin 1.0)

0.84147096

\* (sin 0.1d1)

0.8414709848078965d0

\* (sin #c(1.0 2.0))

#C(3.1657784 1.9596009)

\* pi

3.141592653589793d0

\* (cos pi)

-1.0d0

\* (tan (/ pi 4))

0.9999999999999999d0

\*

Voici les fonctions trigonom triques inverses propos es par Common Lisp :

| | |

| --- | --- |

| nom | fonction |

| asin | inverse de sinus |

| acos | inverse de cosinus |

| atan | inverse de tangent |

Ces fonctions asin et acos renvoient un r sultat complexe si la valeur absolue de l'argument est sup rieure 1 ou si l'argument est complexe. La fonction atan renvoie un r sultat complexe si l'argument est complexe :

\* (asin 0.44)

0.45559868

\* (asin 1.0)

1.5707964

\* (asin 1.1)

#C(1.5707964 -0.4435683)

\* (acos -34)

#C(3.1415927 -4.219291)

\* (acos -34d0)

#C(3.141592653589793d0 -4.219291372012082d0)

\* (atan 2320934029384029384029384023984502938)

1.5707964

\* (atan #c(1.0 2.0))

#C(1.3389726 0.4023595)

\*

Trigonom trie hyperbolique

Les fonctions trigonom triques hyperboliques suivantes existent :

| | | |

| --- | --- | --- |

| nom | fonction | d finition |

| sinh | sinus hyperbolique | ![$\frac{e^x - e^{-x}}{2}$](data:image/png;base64...) |

| cosh | cosinus hyperbolique | ![$\frac{e^x + e^{-x}}{2}$](data:image/png;base64...) |

| tanh | tangent hyperbolique | ![$\frac{e^x - e^{-x}}{e^x + e^{-x}}$](data:image/png;base64...) |

| asinh | sinus hyperbolique inverse | ![$\texttt{log}(x+\sqrt{1+x^2})$](data:image/png;base64...) |

| acosh | cosinus hyperbolique inverse | ![$2\texttt{log}(\sqrt{\frac{x+1}{2}} + \sqrt{\frac{x-1}{2}})$](data:image/png;base64...) |

| atanh | tangent hyperbolique inverse | ![$\frac{\texttt{log}(1+x) - \texttt{log}(1-x)}{2}$](data:image/png;base64...) |

Logarithmes et exponentielles

Les fonctions logarithmiques et exponentielles existent :

| | |

| --- | --- |

| nom | fonction |

| log | logarithme |

| exp | exponentielle naturelle |

| expt | exponentielle d'une base arbitraire |

La fonction log calcule le logarithme n p rien, mais accepte aussi un deuxi me argument facultatif indiquant la base. Exemples :

\* (exp 1)

2.7182817

\* (exp -1)

0.36787945

\ (exp (\ #c(0 1) pi))

#C(-1.0d0 1.2246063538223773d-16)

\* (expt 2 30)

1073741824

\* (log 3)

1.0986123

\* (log (expt 10 9) 2)

29.897354

\*

Op rations bit bit

Les entiers Common Lisp sont cod s en utilisant la rep sentation binaire en compl ment 2. On peut voir un entier comme une suite infinie de bits. Si le nombre est positif, le nombre est pr c d d'une suite infinie de bits 0 et s'il est n gatif, d'une suite infinie de bits 1. Voici les fonctions qui exploitent cette repr sentation :

| | |

| --- | --- |

| nom | fonction |

| logand | et entre les arguments |

| logandc1 | et entre compl ment du premier et deuxi me argument |

| loganc2 | et entre premier argument et compl ment du deuxi me |

| logeql | quivalence entre les arguments |

| logior | ou inclusif entre les deux arguments |

| lognand | compl ment du et entre les arguments |

| lognor | compl ment du ou inclusif entre les arguments |

| lognot | compl ment de l'argument |

| logorc1 | ou inclusif entre compl ment du premier et deuxi me argument |

| logorc2 | ou inclusif entre premier argument et compl ment du deuxi me |

| logxor | ou exclusif entre les arguments |

| logbitp | vrai si un bit est 1 dans l'argument |

| logcount | nombre de bits 1 ou 0 dans l'argument |

| logtest | vrai si des bits sont 1 |

Conversion, troncature, arrondi

Plusieurs fonctions existent pour la troncature et l'arrondi. Ces fonctions prennent toutes deux arguments : un nombre ![$n$](data:image/png;base64...)et un diviseur ![$d$](data:image/png;base64...). Le diviseur est facultatif et sa valeur par d faut est 1. Chacune de ces fonctions renvoie deux valeurs (voir chapitre [13](file:///E%3A%5CIrene_Book%5Cnode158.html#chapmultiplevalues)), un quotient ![$q$](data:image/png;base64...)et un reste ![$r$](data:image/png;base64...)tels que ![$qd + r = n$](data:image/png;base64...). La valeur ![$q$](data:image/png;base64...)est obtenue par une division entre ![$n$](data:image/png;base64...)et ![$d$](data:image/png;base64...), suivie d'une conversion du r sultat en entier. La diff rence entre ces fonctions r side dans la fa on dont est faite cette conversion. Voici les fonctions disponibles :

| | |

| --- | --- |

| nom | fonction |

| floor | r sultat tronqu vers l'infini n gatif |

Publicité

| ceiling | r sultat tronqu vers l'infini positif |

| truncate | r sultat tronqu vers z ro |

| round | r sultat arrondi vers l'entier le plus proche |

Exemples :

\* (floor 234/11 5.4)

3

5.072727

\* (floor -234/11 5.4)

-4

0.3272729

\* (ceiling 234/11 5.4)

4

-0.3272729

\* (ceiling -234/11 5.4)

-3

-5.072727

\* (truncate 234/11 5.4)

3

5.072727

\* (truncate -234/11 5.4)

-3

-5.072727

\* (round 234/11 5.4)

4

-0.3272729

\* (round -234/11 5.4)

-4

0.3272729

\* (floor 233/3)

77

2/3

\* (round 234.444)

234

0.44400024

\*

Les fonctions ffloor, fceiling, ftruncate et fround sont similaires aux fonctions ci-dessus, la seule diff rence que la valeur ![$q$](data:image/png;base64...)est un flottant au lieu d'un entier :

\* (ffloor 23 5)

4.0

3

\* (fround -234/33 2/5)

-18.0

6/55

\* (fceiling 44.234d0 3)

15.0d0

-0.7659999999999982d0

\* (ftruncate 9384593847593847593857938475938579385 3)

3.1281978e+36

1

\*

Pour convertir un nombre rationnel en flottant, ou un flottant en complexe, utiliser coerce :

\* (coerce 234 'float)

234.0

\* (coerce 234 'double-float)

234.0d0

\* (coerce 234/5 'double-float)

46.8d0

\* (coerce 2.234 'complex)

#C(2.234 0.0)

\*

Symboles

Sous-sections

  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode81.html)
  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode82.html)
  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode83.html)
  • (file:///E%3A%5C%5CIrene_Book%5C%5Cnode84.html)

Pr dicats sur les symboles

Les symboles repr sentent un type de donn e unique en Common Lisp. Une caract ristique essentielle des symboles est qu'ils sont uniques, savoir deux suites de caract res identiques dans le m me programme (et dans le m me paquetage), repr sentent le m me symbole. Ceci n'est pas vrai pour les cha nes de caract res, par exemple. Pour les symboles, c'est une qualit essentielle, car en Common Lisp, ils sont utilis s pour nommer des variables et le programmeur est habitu ce que deux occurrences du m me nom de variable r f rencent la m me variable.

Pour tester si un objet Common Lisp est un symbole, utiliser le pr dicat symbolp :

\ \print-level\*

NIL

\ (symbolp \print-level\*)

T

\ \standard-output\*

#<Synonym Stream to SYSTEM:\STDOUT\>

\ (symbolp \standard-output\*)

NIL

\ (symbolp '\standard-output\*)

T

\*

Variables lexicales et sp ciales

Il y a deux types de variables en Common Lisp : variables lexicales et variables sp ciales (ou dynamiques) (en Anglais : lexical variables et special variables) . Les variables lexicales en Common Lisp sont similaires aux variables d'autres langages de programmation. Une telle variable peut tre cr e par un let. Les param tres d'une fonction sont des variables lexicales. Pour des raisons d'efficacit , il n'est pas possible de manipuler la liaison entre un symbole repr sentant une variable lexicale et sa valeur. Les seules op rations permises sont la r cup ration et l'affectation de la valeur. Pour ces deux op rations, le nom de la variable est connu par le compilateur ce qui permet ce dernier de g n rer du code efficace. La port e d'une variable lexicale est limit e une partie du programme d termin e seulement par son texte. Exemple :

\* (let ((x 10))

(defun f (y)

(+ x y)))

F

\* (defun g (x)

(f x))

G

\* (g 3)

13

\*

Ici, il y a deux variables diff rentes dont le nom est x : la premi re est cr e par le let et r f renc e dans f et la deuxi me est cr e implicitement quand g est invoqu e et r f renc e dans le corps de g.

Les variables sp ciales, par contre, sont tr s diff rentes des variables lexicales. La port e d'une variable sp ciale n'est pas limit e au texte du programme. Une telle variable est cr e par defparameter (entre autres). Voici le m me exemple avec une variable sp ciale :

\* (defparameter x 5)

X

\* (let ((x 10))

(defun f (y)

(+ x y)))

F

\* (defun g (x)

(f x))

G

\* (g 3)

6

\* x

5

\*

Publicité

Ici, il y a une seule variable x. Elle est sp ciale car elle est cr e par defparameter. Lorsque f est d finie, cette variable aura la valeur 10 comme dans l'exemple pr c dent. Mais l'appel de g avec l'argument 3 modifie la valeur de la variable x pour la dur e de l'ex cution de g, m me pendant l'appel f.

Les variables sp ciales se comportent d'une fa on tellement diff rente des variable lexicales que les programmeurs Common Lisp ont d cid d'avertir un lecteur ventuel du programme de la pr sence d'une variable sp ciale : la convention est d'entourer le nom d'une variable sp ciale par des ast risques comme pour \print-level\ ou \read-base\.

L'utilisation de variables sp ciales est une technique de programmation importante en Common Lisp. L'utilisation la plus fr quente est d' viter le passage d'un argument une fonction dont la valeur est presque toujours la m me, mais cependant susceptible de changer. Un exemple classique de ce type d'utilisation est illustr par les variables \read-base\ et \print-base\. Celles-ci d terminent la base utiliser pour lire et afficher les nombres. Cette base est presque toujours 10, mais il peut arriver qu'on ait besoin de la changer. Sans variable sp ciale, on a deux possibilit s pour changer le comportement des fonctions de lecture et d'affichage. La premi re est d'utiliser une variable globale comme ceci :

\ \print-base\*

10

\* (print 11)

11

11

\ (setf \print-base\* 8)

10

\* (print 11)

13

13

\ (setf \print-base\* 10)

10

\* (print 11)

11

11

\*

Dans cette exemple, \print-base\* est affect e 8 pour la dur e d'un calcul (ici le calcul trivial 11), puis nouveau affect e 10*. C'est une m thode peu pratique, en particulier si le calcul risque de provoquer une erreur, auquel cas la deuxi me affectation ne sera pas effectu e ( moins de compliquer le code).

Dans l'exemple ci-dessus, on remarque que l' valuation de l'appel print donne deux lignes d'affichage de la part du syst me : la premi re est l'effet de bord de print dont le r sultat est d'afficher la valeur et la deuxi me est la valeur de l'expression (print 11), en l'occurrence la m me que l'argument donn print.

La deuxi me possibilit est d' crire les fonctions de lecture et d'affichage avec un param tre suppl mentaire indiquant la valeur de la base ; ceci introduit beaucoup de code suppl mentaire, souvent le m me chaque fois.

Avec les variables sp ciales, il est possible de changer temporairement une valeur pendant la dur e d'un calcul, sans crainte d'erreur :

\ \print-base\*

10

\* (print 11)

11

11

\ (let ((\print-base\* 8)) (print 11))

13

11

\ \print-base\*

10

\* (print 11)

11

11

\*

Dans cette exemple, on remarque les lignes :

\ (let ((\print-base\* 8)) (print 11))

13

11

La valeur de la variable sp ciale \print-base\ est 8 pendant l'ex cution de la fonction print. La premi re ligne d'affichage donne donc 13. La deuxi me ligne d'affichage (11) repr sente la valeur de l'expression (let ((\print-base\ 8)) (print 11)) enti re. Cette valeur est 11 et lorsque cette valeur est affich e, la valeur de \print-base\ est redevenue 10. Ici, m me si le corps du let provoque une erreur, la valeur de \print-base\* redeviendra 10*.

Pour les variables sp ciales, il est possible de manipuler explicitement la correspondance entre symboles et valeurs. La fonction symbol-value permet d'acc der la valeur d'un symbole et de la changer avec setf :

\ (symbol-value '\print-base\*)

10

\ (setf (symbol-value '\print-base\*) 8)

10

\* 11

13

\ (defparameter \sym\ '\print-base\*)

\SYM\

\ \sym\*

\PRINT-BASE\

\ (symbol-value \sym\*)

10

\ (setf (symbol-value \sym\*) 10)

10

\* 11

11

\*

mots-cl s

Un symbole dont le nom commence par :' est un mot-cl (en Anglais : keyword). Techniquement, le caract re :' ne fait pas partie du nom, mais indique le paquetage (en Anglais : package) dans lequel est contenu le symbole.

Pour tester si un symbole est un mot-cl , utiliser le pr dicat keywordp :

\* (keywordp ':bonjour)

T

\* (keywordp 'bonjour)

NIL

\*

Les mots-cl s sont particuliers pour plusieurs raisons. D'abord, la valeur d'un mot-cl est ce m me mot-cl :

\* :ab

:AB

\* :lskdfjlskdjflskdjf

:LSKDFJLSKDJFLSKDJF

\*

Les mots-cl s permettent de nommer des param tres d'une fonction. C'est leur utilisation principale. Certaines fonctions ont besoin d'un grand nombre de param tres, dont la majorit ne change pas d'une invocation l'autre. Un exemple typique est une fonction de cr ation d'une fen tre dans un syst me de fen trage comme X11. Les param tres d'une telle fonction d terminent la position et les dimensions de la fen tre, la couleur du fond, la profondeur, la fen tre m re, le masque d' v nements, etc.

Dans un langage de programmation sans param tres nomm s, un appel de ce type de fonction est difficile lire et comprendre, car il faut se souvenir de la signification de chaque param tre, puis v rifier la position de chacun. Les param tres nomm s permettent de simplifier consid rablement ce type d'appel. Exemple (de la biblioth que CLX pour le syst me X11) :

(create-window :parent root

:x 10 :y 20

:width 200 :height 300)

Ici un mot-cl est utilis pour nommer l'argument qui suit. L'ordre n'a pas d'importance. L'appel suivant est donc identique au pr c dent :

(create-window :y 20 :x 10

:width 200 :height 300

:parent root)

Autres utilisations des symboles

Les symboles ne sont pas utilis s uniquement pour la repr sentation des variables. chaque symbole est associ e une liste de propri t s (en Anglais : property list) que l'on peut utiliser pour fabriquer une base de donn es simple. La liste des propri t s d'un symbole est une liste dans laquelle un l ment sur deux est un indicateur et un l ment sur deux est une valeur. Les deux sont des objets Common Lisp arbitraires. La fonction get prend deux param tres, un symbole et un indicateur et renvoie la valeur correspondant l'indicateur, ou nil si l'indicateur n'existe pas pour le symbole. Avec setf, il est possible de changer ou cr er la valeur associ e un indicateur. Exemples :

\* (get 'jane 'mother)

NIL

\* (setf (get 'jane 'mother) 'anne)

ANNE

\* (get 'jane 'mother)

ANNE

\* (setf (get 'anne 'profession) 'carpenter)

CARPENTER

\* (get (get 'jane 'mother) 'profession)

CARPENTER

\*

Caract res

=caracteres.tex

;''

Cha nes de caract res

=chaines.tex

;''