Remove `indent'
[jscl.git] / src / numbers.lisp
1 ;;; numbers.lisp
2
3 ;; JSCL is free software: you can redistribute it and/or
4 ;; modify it under the terms of the GNU General Public License as
5 ;; published by the Free Software Foundation, either version 3 of the
6 ;; License, or (at your option) any later version.
7 ;;
8 ;; JSCL is distributed in the hope that it will be useful, but
9 ;; WITHOUT ANY WARRANTY; without even the implied warranty of
10 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 ;; General Public License for more details.
12 ;;
13 ;; You should have received a copy of the GNU General Public License
14 ;; along with JSCL.  If not, see <http://www.gnu.org/licenses/>.
15
16 ;;;; Various numeric functions and constants
17
18 (macrolet ((def (operator initial-value)
19              (let ((init-sym   (gensym))
20                    (dolist-sym (gensym)))
21                `(defun ,operator (&rest args)
22                   (let ((,init-sym ,initial-value))
23                     (dolist (,dolist-sym args)
24                       (setq ,init-sym (,operator ,init-sym ,dolist-sym)))
25                     ,init-sym)))))
26   (def + 0)
27   (def * 1))
28
29 ;; - and / work differently from the above macro.
30 ;; If only one arg is given, it negates it or takes its reciprocal.
31 ;; Otherwise all the other args are subtracted from or divided by it.
32 (macrolet ((def (operator unary-form)
33              `(defun ,operator (x &rest args)
34                 (cond
35                   ((null args) ,unary-form)
36                   (t (dolist (y args)
37                        (setq x (,operator x y)))
38                      x)))))
39   (def - (-   x))
40   (def / (/ 1 x)))
41
42
43 (defun 1+ (x) (+ x 1))
44 (defun 1- (x) (- x 1))
45
46 (defun truncate (x &optional (y 1))
47   (floor (/ x y)))
48
49 (defun integerp (x)
50   (and (numberp x) (= (floor x) x)))
51
52 (defun floatp (x)
53   (and (numberp x) (not (integerp x))))
54
55 (defun minusp (x) (< x 0))
56 (defun zerop (x) (= x 0))
57 (defun plusp (x) (< 0 x))
58
59 (defun signum (x)
60   (if (zerop x) x (/ x (abs x))))
61
62 (macrolet ((def (operator)
63              `(defun ,operator (x &rest args)
64                 (dolist (y args) 
65                   (if (,operator x y)
66                       (setq x    (car args))
67                       (return-from ,operator nil)))
68                 t)))
69   (def >)
70   (def >=)
71   (def =) 
72   (def <)
73   (def <=)
74   (def /=))
75
76 (defconstant pi 3.141592653589793) 
77
78 (defun evenp (x) (= (mod x 2) 0))
79 (defun oddp  (x) (not (evenp x)))
80
81 (macrolet ((def (name comparison)
82              `(defun ,name (x &rest xs)
83                 (dolist (y xs) 
84                   (when (,comparison y x)
85                     (setq x y)))
86                 x)))
87   (def max >)
88   (def min <))
89
90 (defun abs (x) (if (> x 0) x (- x)))
91
92 (defun expt (base power) (expt base              power))
93 (defun exp  (power)      (expt 2.718281828459045 power))
94
95 (defun gcd-2 (a b)
96   (if (zerop b)
97       (abs a)
98     (gcd-2 b (mod a b))))
99
100 (defun gcd (&rest integers)
101   (cond ((null integers)
102          0)
103         ((null (cdr integers))
104          (abs (first integers)))
105         ((null (cddr integers))
106          (gcd-2 (first integers) (second integers)))
107         (t
108          (apply #'gcd (gcd (first integers) (second integers)) (nthcdr 2 integers)))))
109
110 (defun lcm-2 (a b)
111   (if (or (zerop a) (zerop b))
112       0
113     (/ (abs (* a b)) (gcd a b))))
114
115 (defun lcm (&rest integers)
116   (cond ((null integers)
117          1)
118         ((null (cdr integers))
119          (abs (first integers)))
120         ((null (cddr integers))
121          (lcm-2 (first integers) (second integers)))
122         (t
123          (apply #'lcm (lcm (first integers) (second integers)) (nthcdr 2 integers)))))