diff --git a/mats/fl.ms b/mats/fl.ms index 2dd2a3760f..cd9a8a635f 100644 --- a/mats/fl.ms +++ b/mats/fl.ms @@ -26,6 +26,13 @@ (flonum->fixnum (* (+ (ash (most-positive-fixnum) -1) 1) 1.0))) (eq? (most-negative-fixnum) (flonum->fixnum (* (most-negative-fixnum) 1.0))) + (eq? (+ (ash (most-positive-fixnum) -1) 1) + (flonum->fixnum (fl+ (* (+ (ash (most-positive-fixnum) -1) 1) 1.0) 0.5))) + (or (not (fixnum? (inexact->exact (exact->inexact (most-positive-fixnum))))) + (eq? (most-positive-fixnum) + (flonum->fixnum (fl+ (* (most-positive-fixnum) 1.0) 0.5)))) + (eq? (most-negative-fixnum) + (flonum->fixnum (fl- (* (most-negative-fixnum) 1.0) 0.5))) (eq? (flonum->fixnum 0.0) 0) (eq? (flonum->fixnum 1.0) 1) (eq? (flonum->fixnum +4.5) +4) diff --git a/s/cpnanopass.ss b/s/cpnanopass.ss index 3205aab5fa..5788caca01 100644 --- a/s/cpnanopass.ss +++ b/s/cpnanopass.ss @@ -7411,7 +7411,7 @@ (%inline sll ,body (immediate ,(fx- 0 cnt))) body))) (immediate ,mask))))) -< + (define-inline 3 fllp [(e) (build-flonum-extractor 19 12 e)]) diff --git a/s/mathprims.ss b/s/mathprims.ss index 741eea4edc..8401e2f3ae 100644 --- a/s/mathprims.ss +++ b/s/mathprims.ss @@ -317,11 +317,25 @@ ($flonum-sign x))) (set-who! flonum->fixnum - (let ([flmnf (fixnum->flonum (most-negative-fixnum))] - [flmpf (fixnum->flonum (most-positive-fixnum))]) + (let ([flmnf (meta-cond + ;; 64-bit fixnums: -1.0 is the same flonum + [(fl= (fixnum->flonum (most-negative-fixnum)) + (fl- (fixnum->flonum (most-negative-fixnum)) 1.0)) + ;; Find the next lower flonum: + (let loop ([amt 2.0]) + (let ([v (fl- (fixnum->flonum (most-negative-fixnum)) amt)]) + (if (fl= v (fixnum->flonum (most-negative-fixnum))) + (loop (fl* 2.0 amt)) + v)))] + [else + (fl- (fixnum->flonum (most-negative-fixnum)) 1.0)])] + ;; Although adding 1.0 doesn't change the flonum for + ;; 64-bit fixnums, the flonum doesn't fit in a fixnum, so + ;; this is the upper bbound we want either way: + [flmpf (fl+ (fixnum->flonum (most-positive-fixnum)) 1.0)]) (lambda (x) (unless (flonum? x) (flargerr who x)) - (unless (fl<= flmnf x flmpf) + (unless (fl< flmnf x flmpf) ($oops who "result for ~s would be outside of fixnum range" x)) (#3%flonum->fixnum x)))) )