diff --git a/Makefile b/Makefile index 318a8a7..f45526a 100644 --- a/Makefile +++ b/Makefile @@ -185,8 +185,6 @@ top_srcdir = . AUTOMAKE_OPTIONS = foreign SUBDIRS = src scheme doc EXTRA_DIST = README COPYING GPL-3 -#datarootdir=${prefix}/share -#docdir=${datarootdir}/doc/${PACKAGE} dist_doc_DATA = README COPYING GPL-3 all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive diff --git a/Makefile.in b/Makefile.in index 1f3f734..e6c87bb 100644 --- a/Makefile.in +++ b/Makefile.in @@ -185,8 +185,6 @@ top_srcdir = @top_srcdir@ AUTOMAKE_OPTIONS = foreign SUBDIRS = src scheme doc EXTRA_DIST = README COPYING GPL-3 -#datarootdir=${prefix}/share -#docdir=${datarootdir}/doc/${PACKAGE} dist_doc_DATA = README COPYING GPL-3 all: config.h $(MAKE) $(AM_MAKEFLAGS) all-recursive diff --git a/scheme/ikarus.numerics.ss b/scheme/ikarus.numerics.ss index 54816bb..d35d120 100644 --- a/scheme/ikarus.numerics.ss +++ b/scheme/ikarus.numerics.ss @@ -81,32 +81,76 @@ (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)))) + ($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))) + (let ([be ($fxlogand ($flonum-signed-biased-exponent x) + ($fxsub1 ($fxsll 1 11)))]) + ($fx< be 2047))) (define ($flonum-integer? x) - (let ([be (fxlogand ($flonum-signed-biased-exponent x) (sub1 (fxsll 1 11)))]) + (let ([be ($fxlogand ($flonum-signed-biased-exponent x) + ($fxsub1 ($fxsll 1 11)))]) (cond - [(fx= be 2047) ;;; nans and infs + [($fx= be 2047) ;;; nans and infs #f] - [(fx>= be 1075) ;;; magnitue large enough + [($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 + [($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)))]))) + +;;;X (define ($fltruncate x) +;;;X ;(define bv +;;;X ; '#vu8(127 255 255 255 63 255 255 255 31 255 255 255 15 255 255 255 +;;;X ; 7 255 255 255 3 255 255 255 1 255 255 255 0 255 255 255 +;;;X ; 0 127 255 255 0 63 255 255 0 31 255 255 0 15 255 255 +;;;X ; 0 7 255 255 0 3 255 255 0 1 255 255 0 0 255 255 +;;;X ; 0 0 127 255 0 0 63 255 0 0 31 255 0 0 15 255 +;;;X ; 0 0 7 255 0 0 3 255 0 0 1 255 0 0 0 255 +;;;X ; 0 0 0 127 0 0 0 63 0 0 0 31 0 0 0 15 +;;;X ; 0 0 0 7 0 0 0 3 0 0 0 1 0 0 0 0)) +;;;X ;(define bv +;;;X ; '#vu8(255 255 255 255 255 255 255 255 0 0 0 0 0 0 0 0 +;;;X ; 255 255 255 255 255 255 255 254 0 0 0 0 0 0 0 0 +;;;X ; 255 255 255 255 255 255 255 252 0 0 0 0 0 0 0 0 +;;;X ; 255 255 255 255 255 255 255 248 0 0 0 0 0 0 0 0 +;;;X ; 255 255 255 255 255 255 255 240 0 0 0 0 0 0 0 0 +;;;X ; 255 255 255 255 255 255 255 224 0 0 0 0 0 0 0 0 +;;;X ; 255 255 255 255 255 255 255 192 0 0 0 0 0 0 0 0 +;;;X ; 255 255 255 255 255 255 255 128 0 0 0 0 0 0 0 0 +;;;X +;;;X (let ([sbe ($flonum-signed-biased-exponent x)]) +;;;X (let ([be ($fxlogand sbe ($fxsub1 ($fxsll 1 11)))]) +;;;X (cond +;;;X [($fx= be 2047) ;;; nans and infs +;;;X x] +;;;X [($fx>= be 1075) ;;; magnitue large enough +;;;X x] +;;;X [($fx= be 0) ;;; denormalized double +;;;X (if ($fxzero? sbe) 0.0 -0.0)] +;;;X [($fx< be ($fx+ 1075 -52)) ;;; too small to be an integer +;;;X (if ($fxzero? ($fxlogand sbe ($fxsll 1 11))) 0.0 -0.0)] +;;;X [else +;;;X (let ([v ($make-flonum)]) +;;;X +;;;X +;;;X (let ([v ($flonum->exact x)]) +;;;X (or (fixnum? v) (bignum? v)))])))) +;;;X + + + (define (flnumerator x) (unless (flonum? x) @@ -2036,21 +2080,12 @@ [else (if (even? q) q (- q 1))]))))))) - (define ($ratnum-truncate x) (let ([n ($ratnum-n x)] [d ($ratnum-d x)]) (quotient n d))) - ;(define ($flround x) - ; (foreign-call "ikrt_fl_round" x ($make-flonum))) - - ; (let ([e ($flonum->exact x)]) - ; (cond - ; [(not e) x] ;;; infs and nans round to themselves - ; [(ratnum? e) (exact->inexact ($ratnum-round e))] - ; [else (exact->inexact e)]))) - (define (flround x) + ;;; FIXME: flround should preserve the sign of -0.0. (if (flonum? x) (let ([e ($flonum->exact x)]) (cond @@ -2059,6 +2094,7 @@ (error 'flround "not a flonum" x))) (define (round x) + ;;; FIXME: flround should preserve the sign of -0.0. (cond [(flonum? x) (let ([e (or ($flonum->exact x) @@ -2071,6 +2107,7 @@ [else (error 'round "not a number" x)])) (define (truncate x) + ;;; FIXME: fltruncate should preserve the sign of -0.0. (cond [(flonum? x) (let ([e (or ($flonum->exact x) @@ -2082,7 +2119,9 @@ [(or (fixnum? x) (bignum? x)) x] [else (error 'truncate "not a number" x)])) + (define (fltruncate x) + ;;; FIXME: fltruncate should preserve the sign of -0.0. (unless (flonum? x) (error 'fltruncate "not a flonum" x)) (let ([v ($flonum->exact x)]) @@ -2698,3 +2737,57 @@ m))) +(library (ikarus flonums div-and-mod) + (export fldiv flmod fldiv-and-mod) + (import + (ikarus system $flonums) + (ikarus system $fx) + (except (ikarus) fldiv flmod fldiv-and-mod)) + + (define ($flmod n m) + (let ([d0 (fltruncate ($fl/ n m))]) + (let ([m0 ($fl- n ($fl* d0 m))]) + (if ($fl>= m0 0.0) + m0 + (if ($fl>= m 0.0) + ($fl+ m0 m) + ($fl- m0 m)))))) + + (define ($fldiv n m) + (let ([d0 (fltruncate ($fl/ n m))]) + (if ($fl>= n ($fl* d0 m)) + d0 + (if ($fl>= m 0.0) + ($fl- d0 1.0) + ($fl+ d0 1.0))))) + + (define ($fldiv-and-mod n m) + (let ([d0 (fltruncate ($fl/ n m))]) + (let ([m0 ($fl- n ($fl* d0 m))]) + (if ($fl>= m0 0.0) + (values d0 m0) + (if ($fl>= m 0.0) + (values ($fl- d0 1.0) ($fl+ m0 m)) + (values ($fl+ d0 1.0) ($fl- m0 m))))))) + + (define (fldiv n m) + (if (flonum? n) + (if (flonum? m) + ($fldiv n m) + (error 'fldiv "not a flonum" m)) + (error 'fldiv "not a flonum" n))) + + (define (flmod n m) + (if (flonum? n) + (if (flonum? m) + ($flmod n m) + (error 'flmod "not a flonum" m)) + (error 'flmod "not a flonum" n))) + + (define (fldiv-and-mod n m) + (if (flonum? n) + (if (flonum? m) + ($fldiv-and-mod n m) + (error 'fldiv-and-mod "not a flonum" m)) + (error 'fldiv-and-mod "not a flonum" n)))) + diff --git a/scheme/makefile.ss b/scheme/makefile.ss index a92ab7e..181f772 100755 --- a/scheme/makefile.ss +++ b/scheme/makefile.ss @@ -826,8 +826,8 @@ [flceiling i r fl] [flcos i r fl] [fldenominator i r fl] - [fldiv r fl] - [fldiv-and-mod r fl] + [fldiv i r fl] + [fldiv-and-mod i r fl] [fldiv0 r fl] [fldiv0-and-mod0 r fl] [fleven? i r fl] @@ -840,7 +840,7 @@ [fllog i r fl] [flmax i r fl] [flmin i r fl] - [flmod r fl] + [flmod i r fl] [flmod0 r fl] [flnan? i r fl] [flnegative? i r fl] diff --git a/scheme/run-tests.ss b/scheme/run-tests.ss index f74f4ed..ee15d28 100755 --- a/scheme/run-tests.ss +++ b/scheme/run-tests.ss @@ -28,6 +28,7 @@ (tests bignum-to-flonum) (tests string-to-number) (tests input-ports) + (tests fldiv-and-mod) ) (define (test-exact-integer-sqrt) @@ -57,4 +58,5 @@ (test-hashtables) (test-input-ports) (test-bignum-conversion) +(test-fldiv-and-mod) (printf "Happy Happy Joy Joy\n") diff --git a/scheme/tests/fldiv-and-mod.ss b/scheme/tests/fldiv-and-mod.ss new file mode 100755 index 0000000..7c27ea4 --- /dev/null +++ b/scheme/tests/fldiv-and-mod.ss @@ -0,0 +1,46 @@ + +(library (tests fldiv-and-mod) + (export test-fldiv-and-mod) + (import (ikarus)) + + (define (test x1 x2 verify?) + (let-values ([(d m) (fldiv-and-mod x1 x2)]) + (printf "(fldiv-and-mod ~s ~s) = ~s ~s\n" x1 x2 d m) + (when verify? + (assert (= d (fldiv x1 x2))) + (assert (= m (flmod x1 x2))) + (assert (<= 0.0 m)) + (assert (< m (abs x2))) + (assert (= x1 (+ (* d x2) m)))))) + + (define (test-fldiv-and-mod) + (test +17.0 +3.0 #t) + (test +17.0 -3.0 #t) + (test -17.0 +3.0 #t) + (test -17.0 -3.0 #t) + (test +16.0 +3.0 #t) + (test +16.0 -3.0 #t) + (test -16.0 +3.0 #t) + (test -16.0 -3.0 #t) + (test +15.0 +3.0 #t) + (test +15.0 -3.0 #t) + (test -15.0 +3.0 #t) + (test -15.0 -3.0 #t) + (test +17.0 +3.5 #t) + (test +17.0 -3.5 #t) + (test -17.0 +3.5 #t) + (test -17.0 -3.5 #t) + (test +16.0 +3.5 #t) + (test +16.0 -3.5 #t) + (test -16.0 +3.5 #t) + (test -16.0 -3.5 #t) + (test +15.0 +3.5 #t) + (test +15.0 -3.5 #t) + (test -15.0 +3.5 #t) + (test -15.0 -3.5 #t) + (test +17.0 +nan.0 #f) + (test -17.0 +nan.0 #f) + (test +17.0 +inf.0 #f) + (test +17.0 -inf.0 #f) + (test -17.0 +inf.0 #f) + (test -17.0 -inf.0 #f))) diff --git a/scheme/todo-r6rs.ss b/scheme/todo-r6rs.ss index 7deffe8..5808c78 100755 --- a/scheme/todo-r6rs.ss +++ b/scheme/todo-r6rs.ss @@ -332,8 +332,8 @@ [flceiling C fl] [flcos C fl] [fldenominator C fl] - [fldiv S fl] - [fldiv-and-mod S fl] + [fldiv C fl] + [fldiv-and-mod C fl] [fldiv0 S fl] [fldiv0-and-mod0 S fl] [fleven? C fl] @@ -346,7 +346,7 @@ [fllog C fl] [flmax C fl] [flmin C fl] - [flmod S fl] + [flmod C fl] [flmod0 S fl] [flnan? C fl] [flnegative? C fl]