X-Git-Url: http://repo.macrolet.net/gitweb/?a=blobdiff_plain;f=src%2Fcode%2Ffloat.lisp;h=483a6cfd90d624c96547c675c96b3a2d14615e4c;hb=43a526583b7015e6b9945d16e31da72fda1325f5;hp=c8aee59d79ac71a4e7c3d0ddaa6a22022e01a571;hpb=89b82a03269446741ab4b7bba8656d6e37502fe9;p=sbcl.git diff --git a/src/code/float.lisp b/src/code/float.lisp index c8aee59..483a6cf 100644 --- a/src/code/float.lisp +++ b/src/code/float.lisp @@ -753,10 +753,13 @@ ;;; *not* return the second value of truncate, so it must be computed by the ;;; caller if needed. ;;; -;;; In the float case, we pick off small arguments so that compiler can use -;;; special-case operations. We use an exclusive test, since (due to round-off -;;; error), (float most-positive-fixnum) may be greater than -;;; most-positive-fixnum. +;;; In the float case, we pick off small arguments so that compiler +;;; can use special-case operations. We use an exclusive test, since +;;; (due to round-off error), (float most-positive-fixnum) is likely +;;; to be equal to (1+ most-positive-fixnum). An exclusive test is +;;; good enough, because most-positive-fixnum will be one less than a +;;; power of two, and that power of two will be exactly representable +;;; as a float (at least until we get 128-bit fixnums). (defun %unary-truncate (number) (number-dispatch ((number real)) ((integer) number) @@ -775,9 +778,9 @@ ;;; Specialized versions for floats. (macrolet ((def (type name) `(defun ,name (number) - (if (< ,(coerce most-negative-fixnum type) + (if (< ,(coerce sb!xc:most-negative-fixnum type) number - ,(coerce most-positive-fixnum type)) + ,(coerce sb!xc:most-positive-fixnum type)) (truly-the fixnum (,name number)) ;; General -- slow -- case. (multiple-value-bind (bits exp) (integer-decode-float number) @@ -807,13 +810,14 @@ (truly-the fixnum (%unary-round number)) (multiple-value-bind (bits exp) (integer-decode-float number) (let* ((shifted (ash bits exp)) - (rounded (if (and (minusp exp) - (oddp shifted) - (eql (logand bits - (lognot (ash -1 (- exp)))) - (ash 1 (- -1 exp)))) - (1+ shifted) - shifted))) + (rounded (if (minusp exp) + (let ((fractional-bits (logand bits (lognot (ash -1 (- exp))))) + (0.5bits (ash 1 (- -1 exp)))) + (cond + ((> fractional-bits 0.5bits) (1+ shifted)) + ((< fractional-bits 0.5bits) shifted) + (t (if (oddp shifted) (1+ shifted) shifted))))) + )) (if (minusp number) (- rounded) rounded)))))))