; .EnTete "Le-Lisp (c) version 15.2" " " "L'Arithme'tique ge'ne'rique R"
; .EnPied " " "%" " "
; .Chapitre I "L'arithme'tique ge'ne'rique R"
;
; .Centre "*****************************************************************"
; .Centre " Ce fichier est en lecture seule hors du projet ALE de l'INRIA. "
; .Centre " Il est maintenu par ILOG SA, 2 Avenue Gallie'ni, 94250 Gentilly "
; .Centre " (c) Le-Lisp est une marque de'pose'e de l'INRIA "
; .Centre "*****************************************************************"
; .Centre "$Header: genr.ll,v 4.2 88/02/03 11:54:23 kuczynsk Exp $"
(unless (>= (version) 15.2)
(error 'load 'erricf 'genr))
(add-feature 'genr)
(setq #:backup:majuscules #:system:read-case-flag
#:system:read-case-flag ())
; Ce module facilite l'e'criture d'extensions a` l'arithme'tique LeLisp.
; Il re'alise la conversion par de'faut des se'mantiques binaires
; - / quomod en 0- 1/ et truncate respectivement.
; Il effectue la conversion flottante en temps qu'option de dernier
; recours. Il suffit pour cela que les objets programme's re'pondent
; a` la se'mantique float.
; Pour l'utiliser, on pourra, soit installer ses objets comme sous type
; de R, soit simplement charger ce module.
(setq #:sys-package:colon 'R)
; .Section "Ope'rations Binaires"
; Les se'mantiques ge'ne'riques binaires sont :
; + - * / <?> quomod power
(de :+ (n1 n2)
(fadd (float n1) (float n2)))
; Re'duction de la soustraction binaire - a` l'oppose' 0- unaire:
(de :- (n1 n2) (+ n1 (0- n2)))
(de :* (n1 n2); (fmul (float n1) (float n2)))
(fmul (float n1) (float n2)))
; Re'duction de la division binaire / a` l'inverse 1/:
(de :/ (n1 n2) (* n1 (1/ n2)))
(de :<?> (n1 n2) (<?> (float n1) (float n2)))
(defvar #:ex:mod 0)
; Re'duction de la division entie`re au plancher floor:
(de :quomod (n1 n2)
(let ((q (floor (/ n1 (abs n2)))))
(setq #:ex:mod (- n1 (* (abs n2) q)))
(if (< n2 0) (- q) q)))
(de :power (n1 n2) (exp (* n2 (log n1))))
; .SSection "Exponentielle a` deux arguments"
(de ** (x y)
(cond ((< y 0) (/ (** x (- y))))
((integerp y) (:**N x y 1))
((eq x 0) (if (eq 0 y) (/ 0 0) 0))
((eq 1 x) 1)
(T (power x y))))
; Calcule p*(x**n)
(de :**N (x n p)
(if (eq 0 n)
p
(:**N (* x x) (quomod n 2) (if (eq 0 #:ex:mod) p (* x p)))))
; .Section "Ope'rations Unaires"
; Les se'mantiques ge'ne'riques unaires sont :
; abs 0- 1/ float truncate exp log sqrt sin cos asin acos atan
; prin eval numberp integerp rationalp
(de :eval (n) n)
(de :numberp (n) n)
; Par de'faut, les R ne sont pas des entiers:
(de :integerp (r) ())
; Par de'faut, les R ne sont pas des rationnels:
(de :rationalp (r) ())
(de :0- (n) (0- (float n)))
(de :1/ (n) (1/ (float n)))
(de :truncate (n) (truncate (float n)))
(de :exp (r) (exp (float r)))
(de :log (r) (if (< r 0.) (error "log" errgen r)
(log (float r))))
(de :sqrt (r) (if (< r 0.) (error "sqrt" errgen r)
(sqrt (float r))))
(de :atan (r) (atan (float r)))
(de :sin (r) (sin (float r)))
(de :asin (r) (if (or (< r -1.)(> r 1.))
(error "asin" errgen r)
(asin (float r))))
(de :cos (r) (cos (float r)))
(de :acos (r) (if (or (< r -1.)(> r 1.))
(error "acos" errgen r)
(acos (float r))))
; .Section "Re`glage de l'e'criture"
(defvar :prec t)
(de precision k
(unless (null k) (setq :prec (car k)))
:prec)
; .Section "Erreurs Arithme'tiques"
(de :error (nomf msg lapp)
(error nomf
(selectq msg
(RDIV0 "Division entie`re par 0 : ")
(RNOTZ "L'argument n'est pas un entier: ")
(RNOTC "Complexe mal forme'")
(RINC "Argument Complexe")
(T msg))
lapp))
; .Section "Comparaison avec des float ou des fixp"
(de #:float:<?> (x y) (0- (<?> (float y) x)))
(de #:fix:<?> (x y) (0- (<?> y x)))
(defvar #:sys-package:genarith 'R)
(setq #:system:read-case-flag #:backup:majuscules)