X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Fnumbers.lisp;h=330fcdd1c085d6db477d1e974f67a55b5f9cfce2;hb=0d3d3a78055fa485985cda2df688f3cd7e9adb18;hp=a18b5b9957f889fc309249dc8c6cae4c985e292c;hpb=8b0f847a56feacdfcbc8dae20cdc84bb91bf4c98;p=sbcl.git diff --git a/src/code/numbers.lisp b/src/code/numbers.lisp index a18b5b9..330fcdd 100644 --- a/src/code/numbers.lisp +++ b/src/code/numbers.lisp @@ -211,25 +211,6 @@ ;;;; COMPLEXes -(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) - 'single-float) - ((subtypep spec 'double-float) - 'double-float) - #!+long-float - ((subtypep spec 'long-float) - 'long-float) - ((subtypep spec 'rational) - 'rational) - (t - 'real))) - (defun complex (realpart &optional (imagpart 0)) #!+sb-doc "Return a complex number with the specified real and imaginary components." @@ -284,7 +265,7 @@ ((complex rational) (sb!kernel:%imagpart number)) (float - (float 0 number)) + (* 0 number)) (t 0))) @@ -694,14 +675,67 @@ (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.") +(defun ftruncate (number &optional (divisor 1)) + #!+sb-doc + "Same as TRUNCATE, but returns first value as a float." + (macrolet ((ftruncate-float (rtype) + `(let* ((float-div (coerce divisor ',rtype)) + (res (%unary-ftruncate (/ number float-div)))) + (values res + (- number + (* (coerce res ',rtype) float-div)))))) + (number-dispatch ((number real) (divisor real)) + (((foreach fixnum bignum ratio) (or fixnum bignum ratio)) + (multiple-value-bind (q r) + (truncate number divisor) + (values (float q) r))) + (((foreach single-float double-float #!+long-float long-float) + (or rational single-float)) + (if (eql divisor 1) + (let ((res (%unary-ftruncate number))) + (values res (- number (coerce res '(dispatch-type number))))) + (ftruncate-float (dispatch-type number)))) + #!+long-float + ((long-float (or single-float double-float long-float)) + (ftruncate-float long-float)) + #!+long-float + (((foreach double-float single-float) long-float) + (ftruncate-float long-float)) + ((double-float (or single-float double-float)) + (ftruncate-float double-float)) + ((single-float double-float) + (ftruncate-float double-float)) + (((foreach fixnum bignum ratio) + (foreach single-float double-float #!+long-float long-float)) + (ftruncate-float (dispatch-type divisor)))))) + +(defun ffloor (number &optional (divisor 1)) + "Same as FLOOR, but returns first value as a float." + (multiple-value-bind (tru rem) (ftruncate number divisor) + (if (and (not (zerop rem)) + (if (minusp divisor) + (plusp number) + (minusp number))) + (values (1- tru) (+ rem divisor)) + (values tru rem)))) + +(defun fceiling (number &optional (divisor 1)) + "Same as CEILING, but returns first value as a float." + (multiple-value-bind (tru rem) (ftruncate number divisor) + (if (and (not (zerop rem)) + (if (minusp divisor) + (minusp number) + (plusp number))) + (values (+ tru 1) (- rem divisor)) + (values tru rem)))) + +;;; FIXME: this probably needs treatment similar to the use of +;;; %UNARY-FTRUNCATE for FTRUNCATE. +(defun fround (number &optional (divisor 1)) + "Same as ROUND, but returns first value as a float." + (multiple-value-bind (res rem) + (round number divisor) + (values (float res (if (floatp rem) rem 1.0)) rem))) ;;;; comparisons @@ -765,7 +799,8 @@ (defun max (number &rest more-numbers) #!+sb-doc - "Return the greatest of its arguments." + "Return the greatest of its arguments; among EQUALP greatest, return +the first." (do ((nlist more-numbers (cdr nlist)) (result number)) ((null nlist) (return result)) @@ -775,7 +810,8 @@ (defun min (number &rest more-numbers) #!+sb-doc - "Return the least of its arguments." + "Return the least of its arguments; among EQUALP least, return +the first." (do ((nlist more-numbers (cdr nlist)) (result number)) ((null nlist) (return result)) @@ -1200,22 +1236,22 @@ (defun boole (op integer1 integer2) #!+sb-doc "Bit-wise boolean function on two integers. Function chosen by OP: - 0 BOOLE-CLR - 1 BOOLE-SET - 2 BOOLE-1 - 3 BOOLE-2 - 4 BOOLE-C1 - 5 BOOLE-C2 - 6 BOOLE-AND - 7 BOOLE-IOR - 8 BOOLE-XOR - 9 BOOLE-EQV - 10 BOOLE-NAND - 11 BOOLE-NOR - 12 BOOLE-ANDC1 - 13 BOOLE-ANDC2 - 14 BOOLE-ORC1 - 15 BOOLE-ORC2" + 0 BOOLE-CLR + 1 BOOLE-SET + 2 BOOLE-1 + 3 BOOLE-2 + 4 BOOLE-C1 + 5 BOOLE-C2 + 6 BOOLE-AND + 7 BOOLE-IOR + 8 BOOLE-XOR + 9 BOOLE-EQV + 10 BOOLE-NAND + 11 BOOLE-NOR + 12 BOOLE-ANDC1 + 13 BOOLE-ANDC2 + 14 BOOLE-ORC1 + 15 BOOLE-ORC2" (case op (0 (boole 0 integer1 integer2)) (1 (boole 1 integer1 integer2))