Site WWW de Laurent Bloch
Slogan du site

ISSN 2271-3905
Cliquez ici si vous voulez visiter mon autre site, orienté vers des sujets moins techniques.

Pour recevoir (au plus une fois par semaine) les nouveautés de ce site, indiquez ici votre adresse électronique :

Nombres de taille arbitraire avec Bigloo
Article mis en ligne le 7 novembre 2009
dernière modification le 5 décembre 2009

par Laurent Bloch

Il est d’usage que les langages Lisp (et d’autres, comme Ruby) offrent un type de données numériques nommé bignum ; les nombres de ce type peuvent avoir une taille arbitraire, c’est-à-dire que leur nombre de chiffres n’est limité que par l’espace mémoire disponible. Les calculs effectués sur de tels nombres seront bien plus lents qu’avec les types qui correspondent aux dispositifs natifs de l’ordinateur, mais pour certaines applications numériques cela peut être utile. Bigloo offre un type Bignum limité aux nombres entiers.

Avec Bigloo un nombre de type bignum doit être créé explicitement en écrivant ses chiffres dans une chaîne de caractères qui sera convertie en nombre par la procédure string->bignum :

  1. 1:=> (define p (string->bignum "42"))
  2. p
  3. 1:=> (bignum? p)
  4. #t
  5. 1:=> p
  6. #z42
  7. 1:=>

Télécharger

Il est possible d’utiliser la possibilité procurée par Bigloo de créer des variables avec un type explicite, c’est-à-dire une annotation accolée au nom de la variable qui permettra au compilateur de produire un programme plus efficace (cf. pour des explications plus complètes le manuel Bigloo) :

  1. 1:=> (define p::bignum (string->bignum "42"))
  2. p

Télécharger

Voici par exemple un programme de factorielle qui permet d’obtenir le résultat voulu pour d’assez grands nombres :

  1. (define (fact-big n::int)
  2.    (let calcul ((c::int 1)
  3.                 (p::bignum (string->bignum "1")))
  4.       (if (> c n)
  5.           p
  6.           (calcul (+ c 1) (* c p))) ))

Télécharger

Le même programme, prêt à être compilé :

  1. (module fact-big
  2.    (main get-n))
  3.                      ;;
  4. (define (get-n argv)
  5.    (print (fact-big (string->integer (cadr argv)))))
  6.                      ;;
  7. (define (fact-big n::int)
  8.    (let calcul ((c::int 1)
  9.                 (p::bignum (string->bignum "1")))
  10.       (if (> c n)
  11.           p
  12.           (calcul (+ c 1) (* c p))) ))

Télécharger

Compilation et exécution :