0.7.7.26:
[sbcl.git] / src / code / numbers.lisp
index 8e7e6ed..03ba7c5 100644 (file)
       (let ((var (first vars))
            (cases (sort cases #'type-test-order :key #'car)))
        `((typecase ,var
-           ,@(mapcar #'(lambda (case)
-                         `(,(first case)
-                           ,@(generate-number-dispatch (rest vars)
-                                                       (rest error-tags)
-                                                       (cdr case))))
+           ,@(mapcar (lambda (case)
+                       `(,(first case)
+                         ,@(generate-number-dispatch (rest vars)
+                                                     (rest error-tags)
+                                                     (cdr case))))
                      cases)
            (t (go ,(first error-tags))))))
       cases))
       (if (minusp den)
          (values (- num) (- den))
          (values num den))
-    (if (eql den 1)
-       num
-       (%make-ratio num den))))
+    (cond
+      ((eql den 0)
+       (error 'division-by-zero
+             :operands (list num den)
+             :operation 'build-ratio))
+      ((eql den 1) num)
+      (t (%make-ratio num den)))))
 
 ;;; Truncate X and Y, but bum the case where Y is 1.
 #!-sb-fluid (declaim (inline maybe-truncate))
 
 (defun complex (realpart &optional (imagpart 0))
   #!+sb-doc
-  "Builds a complex number from the specified components."
+  "Return a complex number with the specified real and imaginary components."
   (flet ((%%make-complex (realpart imagpart)
           (cond #!+long-float
                 ((and (typep realpart 'long-float)
 
 (defun realpart (number)
   #!+sb-doc
-  "Extracts the real part of a number."
+  "Extract the real part of a number."
   (typecase number
     #!+long-float
     ((complex long-float)
 
 (defun imagpart (number)
   #!+sb-doc
-  "Extracts the imaginary part of a number."
+  "Extract the imaginary part of a number."
   (typecase number
     #!+long-float
     ((complex long-float)
             `(defun ,op (&rest args)
                #!+sb-doc ,doc
                (if (null args) ,init
-                 (do ((args (cdr args) (cdr args))
-                      (res (car args) (,op res (car args))))
-                     ((null args) res))))))
+                   (do ((args (cdr args) (cdr args))
+                        (result (car args) (,op result (car args))))
+                       ((null args) result)
+                     ;; to signal TYPE-ERROR when exactly 1 arg of wrong type:
+                     (declare (type number result)))))))
   (define-arith + 0
     "Return the sum of its arguments. With no args, returns 0.")
   (define-arith * 1
 
 (defun - (number &rest more-numbers)
   #!+sb-doc
-  "Subtracts the second and all subsequent arguments from the first.
-  With one arg, negates it."
+  "Subtract the second and all subsequent arguments from the first; 
+  or with one argument, negate the first argument."
   (if more-numbers
       (do ((nlist more-numbers (cdr nlist))
           (result number))
                                (nd (if (eql t2 1) t3 (* t2 t3))))
                           (if (eql nd 1) nn (%make-ratio nn nd))))))))))))
 
-); Eval-When (Compile)
+) ; EVAL-WHEN
 
 (two-arg-+/- two-arg-+ + add-bignums)
 (two-arg-+/- two-arg-- - subtract-bignum)
        (+ rem divisor)
        rem)))
 
-(macrolet ((def-frob (name op doc)
+(macrolet ((def (name op doc)
             `(defun ,name (number &optional (divisor 1))
                ,doc
                (multiple-value-bind (res rem) (,op number divisor)
                  (values (float res (if (floatp rem) rem 1.0)) rem)))))
-  (def-frob ffloor floor
+  (def ffloor floor
     "Same as FLOOR, but returns first value as a float.")
-  (def-frob fceiling ceiling
+  (def fceiling ceiling
     "Same as CEILING, but returns first value as a float." )
-  (def-frob ftruncate truncate
+  (def ftruncate truncate
     "Same as TRUNCATE, but returns first value as a float.")
-  (def-frob fround round
+  (def fround round
     "Same as ROUND, but returns first value as a float."))
 \f
 ;;;; comparisons
        (result number))
       ((null nlist) (return result))
      (declare (list nlist))
+     (declare (type real number result))
      (if (> (car nlist) result) (setq result (car nlist)))))
 
 (defun min (number &rest more-numbers)
        (result number))
       ((null nlist) (return result))
      (declare (list nlist))
+     (declare (type real number result))
      (if (< (car nlist) result) (setq result (car nlist)))))
 
 (eval-when (:compile-toplevel :execute)
          nil
          (macrolet ((foo (&rest stuff)
                       `(typecase obj2
-                         ,@(mapcar #'(lambda (foo)
-                                       (let ((type (car foo))
-                                             (fn (cadr foo)))
-                                         `(,type
-                                           (and (typep obj1 ',type)
-                                                (,fn obj1 obj2)))))
+                         ,@(mapcar (lambda (foo)
+                                     (let ((type (car foo))
+                                           (fn (cadr foo)))
+                                       `(,type
+                                         (and (typep obj1 ',type)
+                                              (,fn obj1 obj2)))))
                                    stuff))))
            (foo
              (single-float eql)
     (fixnum (lognot (truly-the fixnum number)))
     (bignum (bignum-logical-not number))))
 
-(macrolet ((def-frob (name op big-op)
+(macrolet ((def (name op big-op)
             `(defun ,name (x y)
               (number-dispatch ((x integer) (y integer))
                 (bignum-cross-fixnum ,op ,big-op)))))
-  (def-frob two-arg-and logand bignum-logical-and)
-  (def-frob two-arg-ior logior bignum-logical-ior)
-  (def-frob two-arg-xor logxor bignum-logical-xor))
+  (def two-arg-and logand bignum-logical-and)
+  (def two-arg-ior logior bignum-logical-ior)
+  (def two-arg-xor logxor bignum-logical-xor))
 
 (defun logcount (integer)
   #!+sb-doc
     (13 (boole 13 integer1 integer2))
     (14 (boole 14 integer1 integer2))
     (15 (boole 15 integer1 integer2))
-    (t (error "~S is not of type (mod 16)." op))))
+    (t (error 'type-error :datum op :expected-type '(mod 16)))))
 \f
 ;;;; GCD and LCM
 
 \f
 ;;;; miscellaneous number predicates
 
-(macrolet ((def-frob (name doc)
+(macrolet ((def (name doc)
             `(defun ,name (number) ,doc (,name number))))
-  (def-frob zerop "Is this number zero?")
-  (def-frob plusp "Is this real number strictly positive?")
-  (def-frob minusp "Is this real number strictly negative?")
-  (def-frob oddp "Is this integer odd?")
-  (def-frob evenp "Is this integer even?"))
+  (def zerop "Is this number zero?")
+  (def plusp "Is this real number strictly positive?")
+  (def minusp "Is this real number strictly negative?")
+  (def oddp "Is this integer odd?")
+  (def evenp "Is this integer even?"))