fix bounds checking in flonum->fixnum
The comparison was off for 32-bit plaforms, because it didn't allow fractional increments, The comparison was off for 64-bit platforms, bbecause it didn't account for round-trip failure when starting from the largest fixnum. original commit: 74eb0583ae1b6212fbde459d7486c3d4a0498401
This commit is contained in:
parent
69b597e496
commit
4e808d249a
|
@ -26,6 +26,13 @@
|
||||||
(flonum->fixnum (* (+ (ash (most-positive-fixnum) -1) 1) 1.0)))
|
(flonum->fixnum (* (+ (ash (most-positive-fixnum) -1) 1) 1.0)))
|
||||||
(eq? (most-negative-fixnum)
|
(eq? (most-negative-fixnum)
|
||||||
(flonum->fixnum (* (most-negative-fixnum) 1.0)))
|
(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 0.0) 0)
|
||||||
(eq? (flonum->fixnum 1.0) 1)
|
(eq? (flonum->fixnum 1.0) 1)
|
||||||
(eq? (flonum->fixnum +4.5) +4)
|
(eq? (flonum->fixnum +4.5) +4)
|
||||||
|
|
|
@ -7411,7 +7411,7 @@
|
||||||
(%inline sll ,body (immediate ,(fx- 0 cnt)))
|
(%inline sll ,body (immediate ,(fx- 0 cnt)))
|
||||||
body)))
|
body)))
|
||||||
(immediate ,mask)))))
|
(immediate ,mask)))))
|
||||||
<
|
|
||||||
(define-inline 3 fllp
|
(define-inline 3 fllp
|
||||||
[(e) (build-flonum-extractor 19 12 e)])
|
[(e) (build-flonum-extractor 19 12 e)])
|
||||||
|
|
||||||
|
|
|
@ -317,11 +317,25 @@
|
||||||
($flonum-sign x)))
|
($flonum-sign x)))
|
||||||
|
|
||||||
(set-who! flonum->fixnum
|
(set-who! flonum->fixnum
|
||||||
(let ([flmnf (fixnum->flonum (most-negative-fixnum))]
|
(let ([flmnf (meta-cond
|
||||||
[flmpf (fixnum->flonum (most-positive-fixnum))])
|
;; 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)
|
(lambda (x)
|
||||||
(unless (flonum? x) (flargerr who 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))
|
($oops who "result for ~s would be outside of fixnum range" x))
|
||||||
(#3%flonum->fixnum x))))
|
(#3%flonum->fixnum x))))
|
||||||
)
|
)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user