* Fixed rational? and integer? to handle flonums properly.
This commit is contained in:
parent
83c7fe71b8
commit
9bd65cc447
BIN
src/ikarus.boot
BIN
src/ikarus.boot
Binary file not shown.
|
@ -6,10 +6,12 @@
|
||||||
|
|
||||||
|
|
||||||
(library (ikarus flonums)
|
(library (ikarus flonums)
|
||||||
(export $flonum->exact flonum-parts inexact->exact)
|
(export $flonum->exact $flonum-signed-biased-exponent flonum-parts
|
||||||
|
inexact->exact $flonum-rational? $flonum-integer?)
|
||||||
(import
|
(import
|
||||||
(ikarus system $bytevectors)
|
(ikarus system $bytevectors)
|
||||||
(ikarus system $flonums)
|
(except (ikarus system $flonums) $flonum-signed-biased-exponent
|
||||||
|
$flonum-rational? $flonum-integer?)
|
||||||
(except (ikarus) inexact->exact))
|
(except (ikarus) inexact->exact))
|
||||||
|
|
||||||
(define (flonum-bytes f)
|
(define (flonum-bytes f)
|
||||||
|
@ -38,7 +40,37 @@
|
||||||
(fxsll b2 16)
|
(fxsll b2 16)
|
||||||
(fxsll (fxlogand b1 #b1111) 24))
|
(fxsll (fxlogand b1 #b1111) 24))
|
||||||
(expt 2 24))))))
|
(expt 2 24))))))
|
||||||
|
|
||||||
|
(define ($flonum-signed-biased-exponent x)
|
||||||
|
(let ([b0 ($flonum-u8-ref x 0)]
|
||||||
|
[b1 ($flonum-u8-ref x 1)])
|
||||||
|
(fxlogor (fxsll b0 4) (fxsra b1 4))))
|
||||||
|
|
||||||
|
(define ($flonum-rational? x)
|
||||||
|
(let ([be (fxlogand ($flonum-signed-biased-exponent x) (sub1 (fxsll 1 11)))])
|
||||||
|
(fx< be 2047)))
|
||||||
|
|
||||||
|
(define ($flonum-integer? x)
|
||||||
|
(let ([be (fxlogand ($flonum-signed-biased-exponent x) (sub1 (fxsll 1 11)))])
|
||||||
|
(cond
|
||||||
|
[(fx= be 2047) ;;; nans and infs
|
||||||
|
#f]
|
||||||
|
[(fx>= be 1075) ;;; magnitue large enough
|
||||||
|
#t]
|
||||||
|
[(fx= be 0) ;;; denormalized double, only +/-0.0 is integer
|
||||||
|
(and (fx= ($flonum-u8-ref x 7) 0)
|
||||||
|
(fx= ($flonum-u8-ref x 6) 0)
|
||||||
|
(fx= ($flonum-u8-ref x 5) 0)
|
||||||
|
(fx= ($flonum-u8-ref x 4) 0)
|
||||||
|
(fx= ($flonum-u8-ref x 3) 0)
|
||||||
|
(fx= ($flonum-u8-ref x 2) 0)
|
||||||
|
(fx= ($flonum-u8-ref x 1) 0))]
|
||||||
|
[(fx<= be (fx+ 1075 -52)) ;;; too small to be an integer
|
||||||
|
#f]
|
||||||
|
[else
|
||||||
|
(let ([v ($flonum->exact x)])
|
||||||
|
(or (fixnum? v) (bignum? v)))])))
|
||||||
|
|
||||||
(define ($flonum->exact x)
|
(define ($flonum->exact x)
|
||||||
(let-values ([(pos? be m) (flonum-parts x)])
|
(let-values ([(pos? be m) (flonum-parts x)])
|
||||||
(cond
|
(cond
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
null? pair? weak-pair? symbol? code? not eq? eqv? equal?
|
null? pair? weak-pair? symbol? code? not eq? eqv? equal?
|
||||||
port? input-port? output-port?)
|
port? input-port? output-port?)
|
||||||
(ikarus system $fx)
|
(ikarus system $fx)
|
||||||
|
(ikarus system $flonums)
|
||||||
(ikarus system $pairs)
|
(ikarus system $pairs)
|
||||||
(ikarus system $chars)
|
(ikarus system $chars)
|
||||||
(ikarus system $strings)
|
(ikarus system $strings)
|
||||||
|
@ -76,7 +77,7 @@
|
||||||
[(sys:fixnum? x) #t]
|
[(sys:fixnum? x) #t]
|
||||||
[(sys:bignum? x) #t]
|
[(sys:bignum? x) #t]
|
||||||
[(sys:ratnum? x) #t]
|
[(sys:ratnum? x) #t]
|
||||||
[(sys:flonum? x) #f]
|
[(sys:flonum? x) ($flonum-rational? x)]
|
||||||
[else (error 'rational? "~s is not a number" x)])))
|
[else (error 'rational? "~s is not a number" x)])))
|
||||||
|
|
||||||
(define integer?
|
(define integer?
|
||||||
|
@ -85,7 +86,7 @@
|
||||||
[(sys:fixnum? x) #t]
|
[(sys:fixnum? x) #t]
|
||||||
[(sys:bignum? x) #t]
|
[(sys:bignum? x) #t]
|
||||||
[(sys:ratnum? x) #f]
|
[(sys:ratnum? x) #f]
|
||||||
[(sys:flonum? x) (error 'integer "dunno for ~s" x)]
|
[(sys:flonum? x) ($flonum-integer? x)]
|
||||||
[else #f])))
|
[else #f])))
|
||||||
|
|
||||||
(define exact?
|
(define exact?
|
||||||
|
@ -93,6 +94,7 @@
|
||||||
(cond
|
(cond
|
||||||
[(sys:fixnum? x) #t]
|
[(sys:fixnum? x) #t]
|
||||||
[(sys:bignum? x) #t]
|
[(sys:bignum? x) #t]
|
||||||
|
[(sys:ratnum? x) #t]
|
||||||
[(sys:flonum? x) #f]
|
[(sys:flonum? x) #f]
|
||||||
[else
|
[else
|
||||||
(error 'exact? "~s is not a number" x)])))
|
(error 'exact? "~s is not a number" x)])))
|
||||||
|
|
|
@ -381,7 +381,8 @@
|
||||||
[number? i r]
|
[number? i r]
|
||||||
[bignum? i]
|
[bignum? i]
|
||||||
[ratnum? i]
|
[ratnum? i]
|
||||||
[integer? i]
|
[integer? i r]
|
||||||
|
[rational? i r]
|
||||||
[flonum? i]
|
[flonum? i]
|
||||||
[positive? i r]
|
[positive? i r]
|
||||||
[quotient i r]
|
[quotient i r]
|
||||||
|
@ -565,9 +566,12 @@
|
||||||
[$bytevector-u8-ref $bytes]
|
[$bytevector-u8-ref $bytes]
|
||||||
[$bytevector-set! $bytes]
|
[$bytevector-set! $bytes]
|
||||||
|
|
||||||
[$flonum-u8-ref $flonums]
|
[$flonum-u8-ref $flonums]
|
||||||
[$make-flonum $flonums]
|
[$make-flonum $flonums]
|
||||||
[$flonum-set! $flonums]
|
[$flonum-set! $flonums]
|
||||||
|
[$flonum-signed-biased-exponent $flonums]
|
||||||
|
[$flonum-rational? $flonums]
|
||||||
|
[$flonum-integer? $flonums]
|
||||||
|
|
||||||
[$make-bignum $bignums]
|
[$make-bignum $bignums]
|
||||||
[$bignum-positive? $bignums]
|
[$bignum-positive? $bignums]
|
||||||
|
|
Loading…
Reference in New Issue