(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))
\f
;;;; COMPLEXes
-(defun upgraded-complex-part-type (spec)
+(defun upgraded-complex-part-type (spec &optional environment)
#!+sb-doc
"Return the element type of the most specialized COMPLEX number type that
can hold parts of type SPEC."
+ (declare (ignore environment))
(cond ((unknown-type-p (specifier-type spec))
(error "undefined type: ~S" spec))
((subtypep spec 'single-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
(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 (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 ffloor floor
- "Same as FLOOR, but returns first value as a float.")
- (def fceiling ceiling
- "Same as CEILING, but returns first value as a float." )
- (def ftruncate truncate
- "Same as TRUNCATE, but returns first value as a float.")
- (def fround round
- "Same as ROUND, but returns first value as a float."))
+(defmacro !define-float-rounding-function (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))))
+
+(!define-float-rounding-function ffloor floor
+ "Same as FLOOR, but returns first value as a float.")
+(!define-float-rounding-function fceiling ceiling
+ "Same as CEILING, but returns first value as a float." )
+(!define-float-rounding-function ftruncate truncate
+ "Same as TRUNCATE, but returns first value as a float.")
+(!define-float-rounding-function 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)
(declare (list integers))
(if integers
(do ((result (pop integers) (logior result (pop integers))))
- ((null integers) result))
+ ((null integers) result)
+ (declare (integer result)))
0))
(defun logxor (&rest integers)
(declare (list integers))
(if integers
(do ((result (pop integers) (logxor result (pop integers))))
- ((null integers) result))
+ ((null integers) result)
+ (declare (integer result)))
0))
(defun logand (&rest integers)
(declare (list integers))
(if integers
(do ((result (pop integers) (logand result (pop integers))))
- ((null integers) result))
+ ((null integers) result)
+ (declare (integer result)))
-1))
(defun logeqv (&rest integers)
(declare (list integers))
(if integers
(do ((result (pop integers) (logeqv result (pop integers))))
- ((null integers) result))
+ ((null integers) result)
+ (declare (integer result)))
-1))
(defun lognand (integer1 integer2)