;;;; numbers-test.scm (require-extension test) (use numbers posix) ;; The default "comparator" doesn't know how to deal with extended number types (current-test-comparator (lambda (exp act) (or (equal? exp act) (if (or (and (cplxnum? exp) (number? act)) (and (cplxnum? act) (number? exp))) (and (< (abs (real-part (- exp act))) (current-test-epsilon)) (< (abs (imag-part (- exp act))) (current-test-epsilon))) (and (number? exp) (inexact? exp) (< (abs (- 1 (abs (if (zero? act) (+ 1 exp) (/ exp act))))) (current-test-epsilon))))))) (test-begin "numbers") (current-test-epsilon 0) ;; We want exact comparisons (define max-fix most-positive-fixnum) (define min-fix most-negative-fixnum) ;; The minimal bignum in the sense that any smaller makes it a fixnum (define min-big (+ most-positive-fixnum 1)) (define 64-bits? (##sys#fudge 3)) (print max-fix) (print min-fix) (define (show x) (print (and x (number->string x))) x) ;(set-gc-report! #t) (define max2 (show (+ max-fix max-fix))) (define b1 (show (+ 22 max2))) ; 2147483668 or 4611686018427387928 (define c1 (make-rectangular 33 44)) (define c2 (make-rectangular -1.2 44)) (define b2 (- min-fix 22)) (define r1 (/ 33 44)) (define r2 (/ 1000 44)) ;; Found with the pi-ratios benchmark (find-pi 10 20 50) (define pi 3.14159265358979323881089001960817518141234854964894) (define ratpi 314159265358979323881089001960817518141234854964894/100000000000000000000000000000000000000000000000000) (test-group "basic constructors" (test-assert "some bignum (twice maxint)" (show max2)) (test-assert "some other bignum (2147483668 or 9223372036854775828)" (show b1)) (test-assert "negative bignum" (show b2)) (test-assert "exact complex" (show c1)) (test-assert "inexact complex" (show c2)) (test-assert "rational" (show r1)) ) (test-group "addition" (test "+: no arguments" 0 (+)) (test "+: single argument" 33 (+ 33)) (test "+: adding fixnums" 77 (+ 33 44)) (test "+: adding fixnums (2nd negative)" -11 (+ 33 -44)) (test "+: adding fix/flo" 77.5 (+ 33 44.5)) (test-assert "+: adding fix/big" (show (+ 22 max2))) (test-assert "+: adding fix/rat" (show (+ 22 r1))) (test "+: adding fix/complex" (make-rectangular 132 44) (+ 99 c1)) (test "+: adding complex/fix (inexact)" (make-rectangular 97.8 44) (+ c2 99)) (test "+: flo/flo" 9.0 (+ 3.4 5.6)) (test "+: flo/big" (if 64-bits? 9223372036854775809.4 2147483671.4) (+ 3.4 b1)) (test-assert "+: flo/rat" (show (+ 33.4 r1))) (test "+: flo/comp" (make-rectangular 36.4 44) (+ 3.4 c1)) (test-assert "+: big/rat" (show (+ b1 r1))) (test "+: comp+comp" (make-rectangular 66 88) (+ c1 c1)) (test "+: comp+comp (inexact)" (make-rectangular 31.8 88) (+ c1 c2)) (test "+: multiarg" 132 (+ 33 44 55)) ) (test-group "subtraction" (test "-: negate fix" -33 (- 33)) (test "-: negate most negative fix" min-big (- min-fix)) (test "-: negate flo" -33.2 (- 33.2)) (test-assert "-: negate rat" (show (- r1))) (test-assert "-: negate big (should be -2147483668)" (show (- b1))) (test "-: negate comp" (make-rectangular -33 -44) (- c1)) (test "-: fixnums" -11 (- 33 44)) (test "-: fixnums (2nd negative)" 77 (- 33 -44)) (test-assert "-: fixnums (overflow)" (show (- min-fix min-fix))) (test "-: fix/flo" -11.5 (- 33 44.5)) (test "-: flo/fix" 11.5 (- 44.5 33)) (test-assert "-: fix/big" (show (- 22 b2))) (test-assert "-: big/fix" (show (- b2 22))) (test "-: big/fix (normalizing to fix)" max-fix (- min-big 1)) (test-assert "-: fix/rat" (show (- 22 r1))) (test-assert "-: rat/fix" (show (- r1 22))) (test "-: fix/complex" (make-rectangular 66 -44) (- 99 c1)) (test "-: complex/fix" (make-rectangular -66 44) (- c1 99)) (test "-: complex/fix (inexact)" (make-rectangular -100.2 44) (- c2 99)) (test "-: fix/complex (inexact)" (make-rectangular 100.2 -44) (- 99 c2)) (test "-: fix/complex (negative im)" 98-2i (- 99 1+2i)) (test "-: fix/complex (negative im, inexact)" 98.0-2.0i (- 99 1.0+2.0i)) (test "-: fix/complex (negative real, inexact)" 100.0-2.0i (- 99 -1.0+2.0i)) (test "-: rat/complex (negative real)" 5/2-2i (- 3/2 -1+2i)) (parameterize ((current-test-epsilon 1e-10)) (test "-: flo/flo" 2.2 (- 5.6 3.4))) (test-assert "-: flo/big" (show (- 3.4 b1))) (test-assert "-: big/flo" (show (- b1 3.4))) (test-assert "-: flo/rat" (show (- 3.4 r1))) (test-assert "-: rat/flo" (show (- r1 3.4))) (test-assert "-: big/rat" (show (- b1 r1))) (test-assert "-: rat/big" (show (- r1 b1))) (test "-: flo/comp" (make-rectangular -29.6 -44) (- 3.4 c1)) (test "-: comp/flo" (make-rectangular 29.6 44) (- c1 3.4)) (test "-: comp-comp" 0 (- c1 c1)) (test "-: comp-comp (inexact)" 34.2 (- c1 c2)) (test "-: multiarg" -66 (- 33 44 55)) ) (test-group "multiplication" (test "*: no arguments" 1 (*)) (test "*: single argument" 33 (* 33)) (test "*: multiplying fixnums" 1452 (* 33 44)) (test "*: multiplying fixnums (2nd negative)" -1452 (* 33 -44)) (test "*: multiplying fix/flo" 1468.5 (* 33 44.5)) (test-assert "*: multiplying fix/big (-> 47244640212)" (show (* 22 max2))) (test-assert "*: multiplying fix/rat" (show (* 33 r1))) (test "*: multiplying fix/complex" (make-rectangular 3267 4356) (* 99 c1)) (test "*: multiplying complex/fix (inexact)" (make-rectangular -118.8 4356.0) (* c2 99)) (test "*: flo/flo" 19.04 (* 3.4 5.6)) (test "*: flo/big" (if 64-bits? 9223372036854775.806 2147483.668) (* 0.001 b1)) (test-assert "*: flo/rat" (show (* 3.4 r1))) (test-assert "*: big/rat" (show (* b1 r1))) (test "*: flo/comp" (make-rectangular 112.2 149.6) (* 3.4 c1)) (test "*: comp*comp" (make-rectangular -847 2904) (* c1 c1)) (test "*: comp*comp (inexact)" (make-rectangular -1975.6 1399.2) (* c1 c2)) (test "*: multiarg" 79860 (* 33 44 55)) ) (test-group "division" (test-assert "/: rec. fix" (show (/ 33))) (test-assert "/: rec. flo" (show (/ 33.2))) (test-assert "/: rec. rat" (show (/ r1))) (test-assert "/: rec. big" (show (/ b1))) (test-assert "/: rec. comp" (/ c1)) (test-assert "/: fixnums" (show (/ 33 44))) (test "/: fixnums (both negative, fixnum result)" 1 (show (/ -2 -2))) (test-assert "/: fixnums (2nd negative)" (show (/ 33 -44))) (test-assert "/: fixnums" (show (/ min-fix min-fix))) (test "/: fix/flo" (fp/ 33.0 44.5) (/ 33 44.5)) (test "/: flo/fix" (fp/ 44.5 33.0) (/ 44.5 33)) (test-assert "/: fix/big" (show (/ 22 b2))) (test-assert "/: big/fix" (show (/ b2 22))) (test-assert "/: fix/rat" (show (/ 22 r1))) (test-assert "/: rat/fix" (show (/ r1 22))) (test-assert "/: fix/complex" (show (/ 99 c1))) (test-assert "/: complex/fix" (show (/ c1 99))) (test-assert "/: complex/fix (inexact)" (show (- c2 99))) (test-assert "/: fix/complex (inexact)" (show (- 99 c2))) (test "/: flo/flo" (fp/ 5.6 3.4) (/ 5.6 3.4)) (test-assert "/: flo/big" (show (/ 3.4 b1))) (test-assert "/: big/flo" (show (/ b1 3.4))) (test-assert "/: flo/rat" (show (/ 3.4 r1))) (test-assert "/: rat/flo" (show (/ r1 3.4))) (test-assert "/: big/rat" (show (/ b1 r1))) (test-assert "/: rat/big" (show (/ r1 b1))) (test-assert "/: rat/rat" (show (/ r1 r1))) (test-assert "/: flo/comp" (show (/ 3.4 c1))) (test-assert "/: comp/flo" (show (/ c1 3.4))) (test-assert "/: comp/comp" (show (/ c1 c1))) (test-assert "/: comp/comp (inexact)" (show (/ c1 c2))) (test "/: rat/complex" 1/10-1/5i (/ 1/2 1+2i)) (test "/: rat/complex (negative im)" 1/10+1/5i (/ 1/2 1-2i)) (test "/: rat/complex (negative real)" -1/10-1/5i (/ 1/2 -1+2i)) (test "/: rat/complex (negative real&im)" -1/10+1/5i (/ 1/2 -1-2i)) (test-assert "/: multiarg" (show (/ 66 2 44))) (test-error "/: div by 0" (/ 33 0)) (test "/: div by 0 (inexact)" +inf.0 (/ 33 0.0)) (test-assert "/: big result" (show (/ b1 2))) ) (test-group "quotient" (test "quotient: fix/fix" 2 (quotient 22 11)) (test "quotient: fix/big" 0 (quotient 22 b1)) (test "quotient: fix/big (most negative)" -1 (quotient min-fix (- min-fix))) (test "quotient: big/fix (most negative)" -1 (quotient (- min-fix) min-fix)) (test "quotient: flo/flo" 2.0 (quotient 22.0 11.0)) (test "quotient: fix/flo" 2.0 (quotient 22 11.0)) (test "quotient: flo/fix" 2.0 (quotient 22.0 11)) (test "quotient: flo/big" 0.0 (quotient 22.0 b1)) (test "quotient: big/flo" 2.0 (quotient b1 (/ b1 2.0))) (test-error "quotient: flo/flo (fractional)" (quotient 23.0 11.5)) (test-error "quotient: fix/flo (fractional)" (quotient 23 11.5)) (test-error "quotient: flo/fix (fractional)" (quotient 13.5 6)) ) (test-group "remainder" (test "remainder: fix/fix" 0 (remainder 22 11)) (test "remainder: fix/big" 22 (remainder 22 b1)) (test "remainder: fix/big (most negative)" 0 (remainder min-fix (- min-fix))) (test "remainder: big/fix (most negative)" 0 (remainder (- min-fix) min-fix)) (test "remainder: flo/flo" 0.0 (remainder 22.0 11.0)) (test "remainder: fix/flo" 0.0 (remainder 22 11.0)) (test "remainder: flo/fix" 0.0 (remainder 22.0 11)) (unless 64-bits? ;; We lose so much precision when converting to double this makes no sense (test "remainder: flo/big" 22.0 (remainder 22.0 b1))) (test-error "remainder: flo/flo (fractional)" (remainder 22.5 2.25)) (test-error "remainder: fix/flo (fractional)" (remainder 6 12.5)) (test-error "remainder: flo/fix (fractional)" (remainder 13.5 6)) (unless 64-bits? (test-error "remainder: flo/big (fractional)" (remainder (+ b1 0.5) b1))) ) (test-group "quotient&remainder" (test "quotient&remainder: fix/fix" '(2 0) (receive l (quotient&remainder 22 11) l)) (test "quotient&remainder: fix/big" '(0 22) (receive l (quotient&remainder 22 b1) l)) (test "quotient&remainder: fix/big (most negative)" '(-1 0) (receive l (quotient&remainder min-fix (- min-fix)) l)) (test "quotient&remainder: big/fix (most negative)" '(-1 0) (receive l (quotient&remainder (- min-fix) min-fix) l)) (test "quotient&remainder: flo/flo" '(5.0 2.0) (receive l (quotient&remainder 22.0 4.0) l)) (test "quotient&remainder: flo/fix" '(5.0 2.0) (receive l (quotient&remainder 22.0 4) l)) (test "quotient&remainder: fix/flo" '(5.0 2.0) (receive l (quotient&remainder 22 4.0) l)) (test-error "quotient&remainder: flo/fix (fractional)" (receive l (quotient&remainder 0.1 2) l)) (test-error "quotient&remainder: flo/big (fractional)" (receive l (quotient&remainder 0.5 b1) l)) (test-error "quotient&remainder: big/flo (fractional)" (receive l (quotient&remainder b1 0.5) l)) ) (test-group "gcd" (test "gcd: fix (64-bit)/big" 1 (gcd 907947775416515 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111)) (test 0 (gcd)) (test 6 (gcd 6)) (test 2 (gcd 6 8)) (test 1 (gcd 6 8 5)) (test 1 (gcd 6 -8 5)) (test 2.0 (gcd 6.0 8.0)) (test-error (gcd 6.1 8.0)) (test-error (gcd 6.0 8.1)) (test-error (gcd +inf.0)) (test-error (gcd +nan.0)) (test-error (gcd 6.0 +inf.0)) (test-error (gcd +inf.0 6.0)) (test-error (gcd +nan.0 6.0)) (test-error (gcd 6.0 +nan.0)) (test-error (gcd 1+2i 3+4i)) (test-error (gcd 1/2 3/4))) (test-group "lcm" (test 1 (lcm)) (test 24 (lcm 6 8)) (test 120 (lcm 6 8 5)) (test 24.0 (lcm 6.0 8.0)) (test-error (lcm 6.1 8.0)) (test-error (lcm 6.0 8.1)) (test-error (lcm +inf.0)) (test-error (lcm +nan.0)) (test-error (lcm 6.0 +inf.0)) (test-error (lcm +inf.0 6.0)) (test-error (lcm +nan.0 6.0)) (test-error (lcm 6.0 +nan.0)) (test-error (lcm 1+2i 3+4i)) (test-error (lcm 1/2 3/4))) (test-group "equality" (test "=: fix/fix" #t (= 33 33)) (test "=: fix/flo" #t (= 33 33.0)) (test "=: !fix/fix" #f (= 33 34)) (test "=: !fix/flo" #f (= 33 33.1)) (test "=: !fix/flo (overflow)" #f (= 9007199254740993 9007199254740992.0)) (test "=: !fix/flo (inf)" #f (= 0 +inf.0)) (test "=: !fix/flo (-inf)" #f (= 0 -inf.0)) (test "=: !fix/flo (+nan)" #f (= 0 -nan.0)) (test "=: flo/fix" #t (= 33.0 33)) (test "=: !flo/fix (overflow)" #f (= 9007199254740992.0 9007199254740993)) (test "=: !flo/fix (inf)" #f (= +inf.0 0)) (test "=: !flo/fix (-inf)" #f (= -inf.0 0)) (test "=: !flo/fix (+nan)" #f (= -nan.0 0)) (test "=: flo/flo" #t (= 33.1 33.1)) (test "=: !flo/flo" #f (= 33.1 -33.1)) ;; Flonums are only 53 bits of precision, so it will drop data. ;; Comparison is exact (unless 64-bits? (test "=: big/flo" #t (= b1 (+ 0.0 b1)))) (test "=: big/big" #t (= b1 b1)) (test "=: !big/big" #f (= b2 b1)) (test "=: rat/flo" #t (= r1 (+ r1 0.0))) (test "=: rat/rat" #t (= r1 r1)) (test "=: !rat/rat" #f (= r1 r2)) (test "=: comp/comp" #t (= c1 c1)) (test "=: !comp/comp" #f (= c1 c2)) ) (test-group "generic equality" (test "equal?: fix/fix" #t (equal? 33 33)) (test "equal?: fix/flo" #f (equal? 33 33.0)) (test "equal?: !fix/fix" #f (equal? 33 34)) (test "equal?: !fix/flo" #f (equal? 33 33.1)) (test "equal?: flo/fix" #f (equal? 33.0 33)) (test "equal?: flo/flo" #t (equal? 33.1 33.1)) (test "equal?: !flo/flo" #f (equal? 33.1 -33.1)) (test "equal?: big/flo" #f (equal? b1 (+ 0.0 b1))) (test "equal?: big/big" #t (equal? b1 b1)) (test "equal?: big/big2" #t (equal? b1 (+ 1 b1 -1))) (test "equal?: !big/big" #f (equal? b2 b1)) (test "equal?: rat/flo" #f (equal? r1 (+ r1 0.0))) (test "equal?: rat/rat" #t (equal? r1 r1)) (test "equal?: !rat/rat" #f (equal? r1 r2)) (test "equal?: comp/comp" #t (equal? c1 c1)) (test "equal?: !comp/comp" #f (equal? c1 c2)) (test "equal?: nan/nan" #f (equal? (/ 0.0 0.0) (/ 0.0 0.0))) (test "equal?: nan+nan/nan+nan" #f (equal? (make-rectangular (/ 0.0 0.0) (/ 0.0 0.0)) (make-rectangular (/ 0.0 0.0) (/ 0.0 0.0)))) ) (test-group "greater & greater/equal" (test ">: fix/fix" #t (> 44 33)) (test ">=: fix/fix" #t (>= 44 33)) (test ">: fix/fix/fix" #t (> 44 33 22)) (test ">=: fix/fix/fix" #t (>= 44 33 22)) (test ">: !fix/fix" #f (> 33 44)) (test ">=: !fix/fix" #f (>= 33 44)) (test ">: !fix/fix/fix" #f (> 22 33 44)) (test ">=: !fix/fix/fix" #f (>= 22 33 44)) (test ">: fix/fix" #f (> 33 33)) (test ">=: !fix/fix" #t (>= 33 33)) (test ">: fix/flo" #t (> 44 33.0)) (test ">=: fix/flo" #t (>= 44 33.0)) (test ">: !fix/flo" #f (> 33 44.0)) (test ">=: !fix/flo" #f (>= 33 44.0)) (test ">: !fix/flo" #f (> 33 33.0)) (test ">=: !fix/flo" #t (>= 33 33.0)) (test ">: fix/flo (flo overflow), on 64 bits" #t (> 9007199254740993 9007199254740992.0)) ; 2^53 (test ">=: fix/flo (flo overflow), on 64 bits" #t (>= 9007199254740993 9007199254740992.0)) (test ">: fix/flo (flo underflow), on 64 bits" #f (> -9007199254740992 -9007199254740991.0)) (test ">=: fix/flo (flo underflow), on 64 bits" #f (>= -9007199254740992 -9007199254740991.0)) (test ">: fix/big" #t (> 44 b2)) (test ">=: fix/big" #t (>= 44 b2)) (test ">: !fix/big" #f (> 33 b1)) (test ">=: !fix/big" #f (>= 33 b1)) (test ">: fix/rat" #t (> 44 r1)) (test ">=: fix/rat" #t (>= 44 r1)) (test ">: !fix/rat" #f (> 0 r1)) (test ">=: !fix/rat" #f (>= 0 r1)) (test ">: flo/fix" #t (> 44.0 33)) (test ">=: flo/fix" #t (>= 44.0 33)) (test ">: !flo/fix" #f (> 33.0 44)) (test ">=: !flo/fix" #f (>= 33.0 44)) (test ">: !flo/fix" #f (> 33.0 33)) (test ">=: flo/fix" #t (>= 33.0 33)) (test ">: flo/flo" #t (> 44.0 33.0)) (test ">=: flo/flo" #t (>= 44.0 33.0)) (test ">: !flo/flo" #f (> 33.0 44.0)) (test ">=: !flo/flo" #f (>= 33.0 44.0)) (test ">: flo/big" #t (> 44.0 b2)) (test ">=: flo/big" #t (>= 44.0 b2)) (test ">: flo/fix (flo overflow), on 64 bits" #f (> 9007199254740992.0 9007199254740993)) ; 2^53 (test ">=: flo/fix (flo overflow), on 64 bits" #f (>= 9007199254740992.0 9007199254740993)) (test ">: fix/flo (flo underflow), on 64 bits" #t (> -9007199254740991.0 -9007199254740992)) (test ">=: fix/flo (flo underflow), on 64 bits" #t (>= -9007199254740991.0 -9007199254740992)) (test ">: flo/big (flo overflow)" #f (> 1237940039285380274899124224.0 1237940039285380274899124225)) (test ">=: flo/big (flo overflow)" #f (>= 1237940039285380274899124224.0 1237940039285380274899124225)) (test ">: !flo/big" #f (> 33.0 b1)) (test ">=: !flo/big" #f (>= 33.0 b1)) (test ">: flo/rat" #t (> 44.0 r1)) (test ">=: flo/rat" #t (>= 44.0 r1)) (test ">: !flo/rat" #f (> 0.0 r1)) (test ">=: !flo/rat" #f (>= 0.0 r1)) (test ">: !rat/rat" #f (> r1 r1)) (test ">=: rat/rat" #t (>= r1 r1)) (test ">: flo/nan" #f (> 0.0 +nan.0)) (test ">=: flo/nan" #f (>= 0.0 +nan.0)) (test ">: nan/flo" #f (> +nan.0 0.0)) (test ">=: nan/flo" #f (>= +nan.0 0.0)) (test ">: flo/flo/nan" #f (> 1.0 0.0 +nan.0)) (test ">=: flo/flo/nan" #f (>= 1.0 0.0 +nan.0)) (test ">: big/fix" #t (> b1 33)) (test ">=: big/fix" #t (>= b1 33)) (test ">: !big/fix" #f (> b2 44)) (test ">=: !big/fix" #f (>= b2 44)) (test ">: big/flo" #t (> b1 33.0)) (test ">=: big/flo" #t (>= b1 33.0)) (test ">: big/flo (flo overflow)" #t (> 1237940039285380274899124225 1237940039285380274899124224.0)) (test ">=: big/flo (flo overflow)" #t (>= 1237940039285380274899124225 1237940039285380274899124224.0)) (test ">: !big/flo" #f (> b2 44.0)) (test ">=: !big/flo" #f (>= b2 44.0)) (test ">: big/big" #t (> b1 b2)) (test ">=: big/big" #t (>= b1 b2)) (test ">: !big/big" #f (> b2 b1)) (test ">=: !big/big" #f (>= b2 b1)) (test ">: big/rat" #t (> b1 r1)) (test ">=: big/rat" #t (>= b1 r1)) (test ">: !big/rat" #f (> b2 r1)) (test ">=: !big/rat" #f (>= b2 r1)) (test ">: rat/fix" #f (> r1 2)) (test ">=: rat/fix" #f (>= r1 2)) (test ">: !rat/fix" #f (> r1 44)) (test ">=: !rat/fix" #f (>= r1 44)) (test ">: rat/flo" #t (> r2 2.0)) (test ">=: rat/flo" #t (>= r2 2.0)) (test ">: !rat/flo" #f (> b2 44.0)) (test ">=: !rat/flo" #f (>= b2 44.0)) (test ">: !rat/big" #f (> r1 b1)) (test ">=: !rat/big" #f (>= r1 b1)) (test ">: rat/rat" #t (> r2 r1)) (test ">=: rat/rat" #t (>= r2 r1)) (test ">: !rat/rat" #f (> r1 r2)) (test ">=: !rat/rat" #f (>= r1 r2)) (test ">: rat/flo (flo overflow)" #t (> 1237940039285380274899124224/1237940039285380274899124223 1.0)) (test ">: rat/flo (flo overflow)" #f (> 1237940039285380274899124224/1237940039285380274899124223 1.5)) (test ">=: rat/flo (flo overflow)" #t (>= 1237940039285380274899124224/1237940039285380274899124223 1.0)) (test ">=: rat/flo (flo overflow)" #f (>= 1237940039285380274899124224/1237940039285380274899124223 1.5)) (test ">: rat/flo (flo underflow)" #f (> -1237940039285380274899124224/1237940039285380274899124223 -1.0)) (test ">: rat/flo (flo underflow)" #t (> -1237940039285380274899124224/1237940039285380274899124223 -1.5)) (test ">=: rat/flo (flo underflow)" #f (>= -1237940039285380274899124224/1237940039285380274899124223 -1.0)) (test ">=: rat/flo (flo underflow)" #t (>= -1237940039285380274899124224/1237940039285380274899124223 -1.5)) ) (test-group "less & less/equal" (test "<: !fix/fix" #f (< 44 33)) (test "<=: !fix/fix" #f (<= 44 33)) (test "<: fix/fix/fix" #t (< 33 44 55)) (test "<=: fix/fix/fix" #t (<= 33 44 55)) (test "<: !fix/fix/fix" #f (< 33 55 44)) (test "<=: !fix/fix/fix" #f (<= 33 55 44)) (test "<: !fix/fix/fix" #f (< 44 33 55)) (test "<=: !fix/fix/fix" #f (<= 44 33 55)) (test "<: !fix/fix/fix" #f (< 44 44 44)) (test "<=: fix/fix/fix" #t (<= 44 44 44)) (test "<: fix/fix" #t (< 33 44)) (test "<=: fix/fix" #t (<= 33 44)) (test "<: !fix/fix" #f (< 33 33)) (test "<=: fix/fix" #t (<= 33 33)) (test "<: !fix/flo" #f (< 44 33.0)) (test "<=: !fix/flo" #f (<= 44 33.0)) (test "<: fix/flo" #t (< 33 44.0)) (test "<=: fix/flo" #t (<= 33 44.0)) (test "<: fix/flo (flo overflow), on 64 bits" #f (< 9007199254740993 9007199254740992.0)) ; 2^53 (test "<=: fix/flo (flo overflow), on 64 bits" #f (< 9007199254740993 9007199254740992.0)) (test "<: fix/flo (flo underflow), on 64 bits" #t (< -9007199254740993 -9007199254740992.0)) (test "<=: fix/flo (flo underflow), on 64 bits" #t (<= -9007199254740993 -9007199254740992.0)) (test "<: !fix/flo" #f (< 33.0 33.0)) (test "<=: fix/flo" #t (<= 33.0 33.0)) (test "<: !fix/big" #f (< 44 b2)) (test "<=: !fix/big" #f (<= 44 b2)) (test "<: fix/big" #t (< 33 b1)) (test "<=: fix/big" #t (<= 33 b1)) (test "<: !big/big" #f (< b1 b1)) (test "<=: big/big" #t (<= b1 b1)) (test "<: !fix/rat" #f (< 44 r1)) (test "<=: !fix/rat" #f (<= 44 r1)) (test "<: fix/rat" #t (< 0 r1)) (test "<=: fix/rat" #t (<= 0 r1)) (test "<: !flo/fix" #f (< 44.0 33)) (test "<=: !flo/fix" #f (<= 44.0 33)) (test "<: flo/fix" #t (< 33.0 44)) (test "<=: flo/fix" #t (<= 33.0 44)) (test "<: !flo/flo" #f (< 44.0 33.0)) (test "<=: !flo/flo" #f (<= 44.0 33.0)) (test "<: flo/flo" #t (< 33.0 44.0)) (test "<=: flo/flo" #t (<= 33.0 44.0)) (test "<: !flo/big" #f (< 44.0 b2)) (test "<=: !flo/big" #f (<= 44.0 b2)) (test "<: flo/big" #t (< 33.0 b1)) (test "<=: flo/big" #t (<= 33.0 b1)) (test "<: flo/fix (flo overflow), on 64 bits" #t (< 9007199254740992.0 9007199254740993)) ; 2^53 (test "<=: flo/fix (flo overflow), on 64 bits" #t (< 9007199254740992.0 9007199254740993)) (test "<: flo/fix (flo underflow), on 64 bits" #f (< -9007199254740992.0 -9007199254740993)) (test "<=: flo/fix (flo underflow), on 64 bits" #f (<= -9007199254740992.0 -9007199254740993)) (test "<: flo/big (flo overflow)" #t (< 1237940039285380274899124224.0 1237940039285380274899124225)) (test "<=: flo/big (flo overflow)" #t (<= 1237940039285380274899124224.0 1237940039285380274899124225)) (test "<: !flo/rat" #f (< 44.0 r1)) (test "<=: !flo/rat" #f (<= 44.0 r1)) (test "<: flo/rat" #t (< 0.0 r1)) (test "<=: flo/rat" #t (<= 0.0 r1)) (test "<: flo/nan" #f (< 0.0 +nan.0)) (test "<=: flo/nan" #f (<= 0.0 +nan.0)) (test "<: nan/flo" #f (< +nan.0 0.0)) (test "<=: nan/flo" #f (<= +nan.0 0.0)) (test "<: flo/flo/nan" #f (< 0.0 1.0 +nan.0)) (test "<=: flo/flo/nan" #f (<= 0.0 1.0 +nan.0)) (test "<: !big/fix" #f (< b1 33)) (test "<=: !big/fix" #f (<= b1 33)) (test "<: big/fix" #t (< b2 44)) (test "<=: big/fix" #t (<= b2 44)) (test "<: !big/flo" #f (< b1 33.0)) (test "<=: !big/flo" #f (<= b1 33.0)) (test "<: big/flo" #t (< b2 44.0)) (test "<=: big/flo" #t (<= b2 44.0)) (test "<: big/flo (max flo)" #f (< 1237940039285380274899124224 1237940039285380274899124224.0)) (test "<=: big/flo (max flo)" #t (<= 1237940039285380274899124224 1237940039285380274899124224.0)) (test "<: big/flo (max flo, smaller bignum)" #t (< 1237940039285380274899124223 1237940039285380274899124224.0)) (test "<: big/flo (max flo, smaller bignum)" #t (<= 1237940039285380274899124223 1237940039285380274899124224.0)) (test "<: !big/big" #f (< b1 b2)) (test "<=: !big/big" #f (<= b1 b2)) (test "<: big/big" #t (< b2 b1)) (test "<=: big/big" #t (<= b2 b1)) (test "<: !big/rat" #f (< b1 r1)) (test "<=: !big/rat" #f (<= b1 r1)) (test "<: big/rat" #t (< b2 r1)) (test "<=: big/rat" #t (<= b2 r1)) (test "<: !rat/fix" #f (< r2 2)) (test "<=: !rat/fix" #f (<= r2 2)) (test "<: rat/fix" #t (< r1 44)) (test "<=: rat/fix" #t (<= r1 44)) (test "<: !rat/flo" #f (< r2 2.0)) (test "<=: !rat/flo" #f (<= r2 2.0)) (test "<: rat/flo" #t (< b2 44.0)) (test "<=: rat/flo" #t (<= b2 44.0)) (test "<: rat/big" #t (< r1 b1)) (test "<=: rat/big" #t (<= r1 b1)) (test "<: !rat/rat" #f (< r2 r1)) (test "<=: !rat/rat" #f (<= r2 r1)) (test "<: rat/rat" #t (< r1 r2)) (test "<=: rat/rat" #t (<= r1 r2)) (test "<: rat/flo (flo overflow)" #f (< 1237940039285380274899124224/1237940039285380274899124223 1.0)) (test "<: rat/flo (flo overflow)" #t (< 1237940039285380274899124224/1237940039285380274899124223 1.5)) (test "<=: rat/flo (flo overflow)" #f (<= 1237940039285380274899124224/1237940039285380274899124223 1.0)) (test "<=: rat/flo (flo overflow)" #t (<= 1237940039285380274899124224/1237940039285380274899124223 1.5)) (test "<: rat/flo (flo underflow)" #t (< -1237940039285380274899124224/1237940039285380274899124223 -1.0)) (test "<: rat/flo (flo underflow)" #f (< -1237940039285380274899124224/1237940039285380274899124223 -1.5)) (test "<=: rat/flo (flo underflow)" #t (<= -1237940039285380274899124224/1237940039285380274899124223 -1.0)) (test "<=: rat/flo (flo underflow)" #f (<= -1237940039285380274899124224/1237940039285380274899124223 -1.5)) ) (test-group "complex" (test "real-part" 33 (real-part c1)) (test "real-part of flonum" 1.23 (real-part 1.23)) (test "real-part of fixnum" 123 (real-part 123)) (test "real-part of ratnum" 1/2 (real-part 1/2)) (test "real-part of bignum" b1 (real-part b1)) (test "real-part of negative flonum" -1.23 (real-part -1.23)) (test "real-part of negative fixnum" -123 (real-part -123)) (test "real-part of negative ratnum" -1/2 (real-part -1/2)) (test "real-part of negative bignum" (- b1) (real-part (- b1))) (test "imag-part" 44 (imag-part c1)) (test "imag-part of flonum" 0.0 (imag-part 1.23)) (test "imag-part of fixnum" 0 (imag-part 123)) (test "imag-part of ratnum" 0 (imag-part 1/2)) (test "imag-part of bignum" 0 (imag-part b1)) (test-assert "make-polar" (show (make-polar 33 44))) (test "magnitude" 8 (magnitude 0+8i)) (test "magnitude" 1/2 (magnitude 0+1/2i)) (test "magnitude of flonum" 1.23 (magnitude 1.23)) (test "magnitude of fixnum" 123 (magnitude 123)) (test "magnitude of ratnum" 1/2 (magnitude 1/2)) (test "magnitude of bignum" b1 (magnitude b1)) (test "magnitude of negative flonum" 1.23 (magnitude -1.23)) (test "magnitude of negative fixnum" 123 (magnitude -123)) (test "magnitude of negative ratnum" 1/2 (magnitude -1/2)) (test "magnitude of negative bignum" b1 (magnitude (- b1))) (test-assert "angle" (show (angle c1))) (test "angle of flonum" 0.0 (angle 1.23)) (test "angle of fixnum" 0.0 (angle 123)) (test "angle of ratnum" 0.0 (angle 1/2)) (test "angle of bignum" 0.0 (angle b1)) (test "angle of negative flonum" pi (angle -1.23)) (test "angle of negative fixnum" pi (angle -123)) (test "angle of negative ratnum" pi (angle -1/2)) (test "angle of negative bignum" pi (angle (- b1))) ) (test-group "rational" (test "numerator" 3 (numerator r1)) (test-assert "numerator" (show (numerator b1))) (test "numerator" 33 (numerator 33)) (test "denominator" 4 (denominator r1)) (test "denominator" 1 (denominator b1)) (test "denominator" 1 (denominator 33)) ) (test-group "misc" (test "inexact->exact" 2589569785738035/1125899906842624 (inexact->exact 2.3)) (test-error "inexact->exact +inf" (inexact->exact +inf.0)) (test-error "inexact->exact -inf" (inexact->exact -inf.0)) (test-error "inexact->exact -NaN" (inexact->exact +nan.0)) (test "sqrt (integer result)" 4 (sqrt 16)) (test "sqrt (exact result)" 1/2 (sqrt 1/4)) (test "sqrt (inexact result)" 1.4142135623730951 (sqrt 2)) (test "sqrt (inexact input)" 2.0 (sqrt 4.0)) (test "sqrt (exact large number)" max-fix (sqrt (* max-fix max-fix))) (test-error "exact-integer-sqrt (nonint flonum)" (exact-integer-sqrt 1.5)) (test-error "exact-integer-sqrt (ratnum)" (exact-integer-sqrt 1/2)) (test-error "exact-integer-sqrt (int flonum)" (exact-integer-sqrt 4.0)) (test "exact-integer-sqrt (w/o rest)" (list max-fix 0) (receive x (exact-integer-sqrt (* max-fix max-fix)) x)) (test "exact-integer-sqrt (with rest)" (list max-fix 5) (receive x (exact-integer-sqrt (+ (* max-fix max-fix) 5)) x)) (test "exact-integer-nth-root without rest" (list 3 0) (receive x (exact-integer-nth-root 243 5) x)) (test "exact-integer-nth-root with rest" (list 3 47) (receive x (exact-integer-nth-root 128 4) x)) (test "exact-integer-nth-root with insanely large base" (list 1 4) (receive x (exact-integer-nth-root 5 (if 64-bits? 10000000000 100000000)) x)) (test "expt" 16 (expt 2 4)) (test-assert "expt" (show (expt 2 100))) ;; The next three according to R7RS (test "expt 0.0^0.0)" 1.0 (expt 0.0 0.0)) (test "expt 0.0^{pos}" 0.0 (expt 0.0 1.0)) ;; An error is not mandatory: ;; "[...] either an error is signalled or an unspecified number is returned." ;(test-error "expt 0.0^{neg}" (expt 0.0 -1.0)) ;; R7 doesn't say anything specific about fixnums, so I guess this should behave the same (test "expt 0^0" 1 (expt 0 0)) (test "expt 0^{pos}" 0 (expt 0 1)) (test-error "expt 0^{neg}" (expt 0 -1)) (test "expt (rat base)" 1/4 (expt 1/2 2)) (test "expt (rat exponent)" 2 (expt 16 1/4)) (test "expt (negative rat exponent)" 1/2 (expt 16 -1/4)) (test "expt (inexact from rat exponent)" 1.1040895136738123 (expt 2 1/7)) (test "expt (> 1 rat exponent)" 1/512 (expt 1/64 3/2)) (test "expt (rat base & exponent)" 1/2 (expt 1/4 1/2)) (parameterize ((current-test-epsilon 1e-10)) (test "expt (negative w/ rat exponent)" 1.4142135623731+1.41421356237309i (expt -16 1/4))) (test-assert "expt" (show (expt 2 2.0))) (test-assert "expt" (show (expt 2 -1))) (test "expt between double and 64-bit integer value" 994014980014994001 (expt 999 6)) ;; Why do these work with epsilon set to 0? (test "expt with complex result" -1.836909530733566e-16-1.0i (expt -1 1.5)) (test "exact expt with complex number" 0+1i (expt 0+1i 5)) (test "exact expt with complex number, real result" -1 (expt 0+1i 6)) (test "inexact expt with complex number" 0.0+1.0i (expt 0.0+1.0i 5.0)) (test "inexact expt with complex number, real result" -1.0 (expt 0.0+1.0i 6.0)) (parameterize ((current-test-epsilon 1e-10)) (test "inexact noninteger expt with complex number" 1.4142135623731+1.41421356237309i (expt 0.0+4.0i 0.5))) (test "exp with complex numbers" 1.4686939399158851+2.2873552871788423i (exp 1+i)) (test "log of exp = 1" 1.0 (log (exp 1))) (test "log of -1" 0.0+3.141592653589793i (log -1)) (test "log with complex number" 0.0+1.5707963267948966i (log +i)) (test "exp(log(x)) = x" 2.0-3.0i (exp (log 2.0-3.0i))) (test "log(exp(x)) = x" 2.0-3.0i (log (exp 2.0-3.0i))) (letrec ((fac (lambda (n) (if (zero? n) 1 (* n (fac (- n 1))) ) ) ) ) (test-assert "bigfac" (show (fac 100))) (test "signum" 1 (signum b1)) (test "signum" -1 (signum -2)) ) (test "most-negative-fixnum + most-negative-fixnum = 2 * most-negative-fixnum" (* 2 most-negative-fixnum) (+ most-negative-fixnum most-negative-fixnum)) (test "most-negative-fixnum - most-negative-fixnum = 0" 0 (- most-negative-fixnum most-negative-fixnum)) (test "most-positive-fixnum + most-positive-fixnum = 2 * most-positive-fixnum" (* 2 most-positive-fixnum) (+ most-positive-fixnum most-positive-fixnum)) (test "most-positive-fixnum - most-positive-fixnum = 0" 0 (- most-positive-fixnum most-positive-fixnum)) ) (test-group "R5RS" (test "+" 7 (+ 3 4)) (test "+" 3 (+ 3)) (test "+" 0 (+)) (test "*" 4 (* 4)) (test "*" 1 (*)) (test "-" -1 (- 3 4)) (test "-" -6 (- 3 4 5)) (test "-" -3 (- 3)) (test-assert "/ (3/20)" (show (/ 3 4 5))) (test-assert "/ (1/3)" (show (/ 3))) (test "numerator" 3 (numerator (/ 6 4))) (test "denominator" 2 (denominator (/ 6 4))) (test "complex?" #t (complex? c1)) (test "complex?" #t (complex? 3)) (test "real?" #t (real? 3)) (test "real?" #t (real? (make-rectangular -2.5 0.0))) (test "real?" #t (real? 1e0)) (test "rational?" #t (rational? (/ 6 10))) (test-assert "check rational" (show (/ 6 3))) (test "rational?" #t (rational? (/ 6 3))) (test "integer?" #t (integer? (make-rectangular 3 0))) (test "integer?" #f (integer? 1+3i)) (test "integer?" #t (integer? 3.0)) (test "integer?" #t (integer? (/ 8 4))) (test "integer?" #f (integer? 1/2)) (test "exact-integer?" #t (exact-integer? (make-rectangular 3 0))) (test "exact-integer?" #f (exact-integer? 1+3i)) (test "exact-integer?" #f (exact-integer? 3.0)) (test "exact-integer?" #t (exact-integer? (/ 8 4))) (test "exact-integer?" #f (exact-integer? 1/2)) (test "max" 4 (max 3 4)) (test "max" 4.0 (max 3.9 4)) (test "modulo" 1 (modulo 13 4)) (test "modulo" 1.0 (modulo 13.0 4)) (test "modulo" 1.0 (modulo 13 4.0)) (test-error "modulo" (modulo 13.1 4.0)) (test-error "modulo" (modulo 13.0 4.1)) (test "remainder" 1 (remainder 13 4)) (test-error "remainder" (remainder 13.1 4.0)) (test-error "remainder" (remainder 13.0 4.1)) (test "modulo" 3 (modulo -13 4)) (test "remainder" -1 (remainder -13 4)) (test "modulo" -3 (modulo 13 -4)) (test "remainder" 1 (remainder 13 -4)) (test "modulo" -1 (modulo -13 -4)) (test "remainder" -1 (remainder -13 -4)) (test "remainder" -1.0 (remainder -13 -4.0)) (test-assert (even? 2)) (test-assert (not (even? 1))) (test-assert (even? -2)) (test-assert (not (even? -1))) (test-assert (even? 2.0)) (test-assert (not (even? 1.0))) (test-assert (even? -2.0)) (test-assert (not (even? -1.0))) (test-error (even? 2.1)) (test-error (even? -2.3)) (test-error (even? +inf.0)) (test-error (even? +nan.0)) (test-assert (even? (* most-positive-fixnum 2))) (test-assert (not (even? (+ (* most-positive-fixnum 2) 1)))) (test-assert (odd? (+ (* most-positive-fixnum 2) 1))) (test-assert (not (odd? (* most-positive-fixnum 2)))) (test-error (even? 2.0+3.0i)) (test-error (even? 2+3i)) (test-error (odd? 2.0+3.0i)) (test-error (odd? 2+3i)) (test "floor" -5.0 (floor -4.3)) (test "ceiling" -4.0 (ceiling -4.3)) (test "truncate" -4.0 (truncate -4.3)) (test "round" -4.0 (round -4.3)) (test "floor" 3.0 (floor 3.5)) (test "ceiling" 4.0 (ceiling 3.5)) (test "truncate" 3.0 (truncate 3.5)) (test "round" 4.0 (round 3.5)) (test "round" 4.0 (round 4.5)) (test "round" 4 (round (/ 7 2))) (test "round" 7 (round 7)) (test "rationalize (1/3)" 1/3 (rationalize (inexact->exact .3) (/ 1 10))) (test "rationalize (#i1/3)" #i1/3 (rationalize .3 (/ 1 10))) ) (test-group "bitwise ops" (test "and" 1 (bitwise-and #xff #x1)) (test "ior" #xf (bitwise-ior #x0f #x1)) (test "xor" 14 (bitwise-xor #x0f #x1)) (test-assert "not" (show (bitwise-not #x0f))) (test 60 (arithmetic-shift 15 2)) (test 3 (arithmetic-shift 15 -2)) (test -60 (arithmetic-shift -15 2)) (test -4 (arithmetic-shift -15 -2)) ; 2's complement (test -1 (arithmetic-shift -31 most-negative-fixnum)) (test 0 (arithmetic-shift 31 most-negative-fixnum)) (test-error (arithmetic-shift 0.1 2)) ;; XXX Do the following two need to fail? Might as well use the integral value (test-error (arithmetic-shift #xf 2.0)) (test-error (arithmetic-shift #xf -2.0)) (test-error (arithmetic-shift #xf 2.1)) (test-error (arithmetic-shift #xf -2.1)) (test-error (arithmetic-shift +inf.0 2)) (test-error (arithmetic-shift +nan.0 2)) (when 64-bits? (test 0 (arithmetic-shift (expt 2 31) (- (expt 2 31))))) ;; by Jeremy Sydik (let ((leftrot32 (lambda (value amount) (let ((shifted (arithmetic-shift value amount))) (let ((anded (bitwise-and #xFFFFFFFF shifted))) (bitwise-ior anded (arithmetic-shift shifted -32)))) ))) (test "leftrot32 28" 268435456 (leftrot32 1 28)) (test "leftrot32 29" 536870912 (leftrot32 1 29)) (test "leftrot32 30" 1073741824 (leftrot32 1 30))) ) (test-group "string conversion" (test-assert "fix" (number->string 123)) (test-assert "fix/base" (number->string 123 16)) (test-assert "flo" (number->string 99.2)) (test-assert "big" (number->string b1)) (test-assert "big/base" (number->string b1 2)) (test-assert "rat" (number->string r1)) (test-assert "comp" (number->string c1)) (test "fix" 123 (string->number "123")) (test "fix/base" 255 (string->number "ff" 16)) (test "fix/base-o" 14 (string->number "16" 8)) (test "fix/unusual-base" 194 (string->number "1234" 5)) (test "fix/wrong-base" #f (string->number "1234" 4)) (test-error "fix/invalid-base" (string->number "1234" 0)) (test-error "fix/invalid-base" (string->number "1234" 1)) (test "flo" 123.23 (string->number "123.23")) (test "flo2" 100.0 (string->number "1e2")) (test-assert "big" (show (string->number "123873487384737447"))) (test-assert "big/neg" (show (string->number "-123873487384737447"))) (test-assert "big/pos" (show (string->number "+123873487384737447"))) (test-assert "rat" (show (string->number "123/456"))) (test-assert "rat/neg" (show (string->number "-123/456"))) (test-assert "rat/pos" (show (string->number "+123/456"))) (test-assert "rat2" (show (string->number "#o123/456"))) (test "rat/inexact" (/ 123.0 456) (show (string->number "#i123/456"))) (test "invalid rat" #f (string->number "123/0")) (test-assert "comp" (show (string->number "+12i"))) (test-assert "comp" (show (string->number "12+34i"))) (test-assert "comp" (show (string->number "-i"))) (test-assert "comp" (show (string->number "99@55"))) (test-assert "comp" (show (string->number "1/2@3/4"))) (test-assert "comp2" (show (string->number "#x99+55i"))) ;; This is to check for a silly problem cause by representing numbers exactly ;; all the way until the end, then converting to inexact. This "silly problem" ;; could probably be exploited in a resource consumption attack. (let* ((t1 (current-seconds)) (i1 (string->number "1e1000000")) (i2 (string->number "1.0e1000000")) (e1 (string->number "#e1e1000000")) (e2 (string->number "#e1.0e1000000")) (t2 (current-seconds))) (test-assert "read time for inexacts with large positive exp isn't insanely high" (< (- t2 t1) 2)) (test "inexact read back are equal" i1 i2) (test "inexact are inf" i1 +inf.0) (test "exact are equal" e1 e2) (test "exact are false" e1 #f)) (let* ((t1 (current-seconds)) (i1 (string->number "-1e1000000")) (i2 (string->number "-1.0e1000000")) (e1 (string->number "#e-1e1000000")) (e2 (string->number "#e-1.0e1000000")) (t2 (current-seconds))) (test-assert "read time for inexacts with large positive exp isn't insanely high" (< (- t2 t1) 2)) (test "negative inexact read back are equal" i1 i2) (test "negative inexact are negative inf" i1 -inf.0) (test "negative exact are equal" e1 e2) (test "negative exact are false" e1 #f)) (let* ((t1 (current-seconds)) (i1 (string->number "1e-1000000")) (i2 (string->number "1.0e-1000000")) (e1 (string->number "#e1e-1000000")) (e2 (string->number "#e1.0e-1000000")) (t2 (current-seconds))) (test-assert "read time for inexacts with large negative exp isn't insanely high" (< (- t2 t1) 2)) (test "inexact read back are equal" i1 i2) (test "inexact are 0" i1 +0.0) (test "exact are equal" e1 e2) (test "exact are false" e1 #f)) ) (test-group "non-standard type procedures" (test "fixnum" #t (fixnum? max-fix)) (test "bignum" #t (bignum? b1)) (test "bignum" #t (bignum? min-big)) (test "ratnum" #t (ratnum? r1)) (test "nan: fix" #f (nan? 1)) (test "nan: flo" #f (nan? 1.0)) (test "nan: +inf" #f (nan? (/ 1.0 0.0))) (test "nan: -inf" #f (nan? (/ -1.0 0.0))) (test "nan: nan" #t (nan? (/ 0.0 0.0))) (test "nan: nan+nani" #t (nan? (make-rectangular (/ 0.0 0.0) (/ 0.0 0.0)))) (test "nan: flo+nani" #t (nan? (make-rectangular 1.0 (/ 0.0 0.0)))) (test "nan: nan+floi" #t (nan? (make-rectangular (/ 0.0 0.0) 1.0))) (test "finite: fix" #t (finite? 1)) (test "finite: flo" #t (finite? 1.0)) (test "finite: +inf" #f (finite? (/ 1.0 0.0))) (test "finite: -inf" #f (finite? (/ 1.0 0.0))) (test "finite: nan" #f (finite? (/ 0.0 0.0))) (test "finite: nan+floi" #f (finite? (make-rectangular (/ 0.0 0.0) 1.0))) (test "finite: inf+infi" #f (finite? (make-rectangular (/ 1.0 0.0) (/ 1.0 0.0)))) (test "finite: flo+infi" #f (finite? (make-rectangular 1.0 (/ 1.0 0.0)))) (test "finite: inf+floi" #f (finite? (make-rectangular (/ 1.0 0.0) 1.0))) (test "infinite: fix" #f (infinite? 1)) (test "infinite: flo" #f (infinite? 1.0)) (test "infinite: +inf" #t (infinite? (/ 1.0 0.0))) (test "infinite: -inf" #t (infinite? (/ 1.0 0.0))) (test "infinite: nan" #f (infinite? (/ 0.0 0.0))) (test "infinite: inf+infi" #t (infinite? (make-rectangular (/ 1.0 0.0) (/ 1.0 0.0)))) (test "infinite: flo+infi" #t (infinite? (make-rectangular 1.0 (/ 1.0 0.0)))) (test "infinite: inf+floi" #t (infinite? (make-rectangular (/ 1.0 0.0) 1.0))) (test "cplxnum: compintintnum" #t (cplxnum? c1)) (test "cplxnum: compintflointnum" #t (cplxnum? 1.0+1i)) (test "cplxnum: compflointnum" #t (cplxnum? c2)) (test "cplxnum: compfloflonum" #t (cplxnum? 3.4-4.3i)) (test "not cplxnum: fixnum" #f (cplxnum? 1)) (test "rectnum: compintintnum" #t (rectnum? c1)) (test "rectnum: compintflointnum" #t (rectnum? 1.0+1i)) (test "not rectnum: compflointum" #f (rectnum? c2)) (test "compnum: compfloflonum" #t (compnum? 3.4-4.3i)) (test "compnum: compflointnum" #t (compnum? 1.0+1i)) (test "not compnum: compintintnum" #f (compnum? c1)) (test "cintnum: intflonum" #t (cintnum? 1.0)) (test "cintnum: fixnum" #t (cintnum? 3)) (test "cintnum: bignum" #t (cintnum? b1)) (test "cintnum: compintintnum" #t (cintnum? c1)) (test "cflonum: intflonum" #t (cflonum? 1.0)) (test "cflonum: flonum" #t (cflonum? 3.4)) (test "cflonum: compfloflonum" #t (cflonum? 3.4-4.3i)) (test "cflonum: compfloflonum" #t (cflonum? c2)) ) ;; The usual comparator doesn't work, because zero or a very small number ;; is many times any other small number, but the absolute difference should ;; be minimal, so we compare for that instead. (parameterize ((current-test-epsilon 1e-9) (current-test-comparator (lambda (exp act) (or (and (nan? exp) (nan? act)) (and (< (abs (- (real-part exp) (real-part act))) (current-test-epsilon)) (< (abs (- (imag-part exp) (imag-part act))) (current-test-epsilon))))))) ;; We're using (acos (cos x)) instead of just (acos y) because we want ;; to test the compiler's specialization rules of cos output. (test-group "trigonometric functions" (test-group "flonums" ;; Note: we don't *actually* distinguish -nan from +nan, but whatever :) (test "acos(-inf)" -nan.0 (acos -inf.0)) (test "acos()" -nan.0 (acos -1e100)) (test "cos(-1/3pi)" 0.5 (cos (- (/ pi 3)))) (test "acos(cos(-1/3pi))" (/ pi 3) (acos (cos (- (/ pi 3))))) (test "cos(-1/4pi)" 0.7071067811865476 (cos (- (/ pi 4)))) (test "acos(cos(-1/4pi))" (/ pi 4) (acos (cos (- (/ pi 4))))) (test "cos(-1/2pi)" 0.0 (cos (- (/ pi 2)))) (test "acos(cos(-1/2pi))" (/ pi 2) (acos (cos (- (/ pi 2))))) (test "cos(-pi)" -1.0 (cos (- pi))) (test "acos(cos(-pi))" pi (acos (cos (- pi)))) (test "cos(0)" 1.0 (cos 0.0)) (test "acos(cos(0))" 0.0 (acos (cos 0.0))) (test "cos( 1/4pi)" 0.7071067811865476 (cos (/ pi 4))) (test "acos(cos( 1/4pi))" (/ pi 4) (acos (cos (/ pi 4)))) (test "cos( 1/3pi)" 0.5 (cos (/ pi 3))) (test "acos(cos( 1/3pi))" (/ pi 3) (acos (cos (/ pi 3)))) (test "cos( 1/2pi)" 0.0 (cos (/ pi 2))) (test "acos(cos( 1/2pi))" (/ pi 2) (acos (cos (/ pi 2)))) (test "cos( 2/3pi)" -0.5 (cos (/ (* 2 pi) 3))) (test "acos(cos( 2/3pi))" (/ (* 2 pi) 3) (acos (cos (/ (* 2 pi) 3)))) (test "cos( 3/4pi)" -0.7071067811865476 (cos (* (/ pi 4) 3))) (test "acos(cos( 3/4pi))" (* (/ pi 4) 3) (acos (cos (* (/ pi 4) 3)))) (test "cos( pi)" -1.0 (cos pi)) (test "acos(cos( pi))" pi (acos (cos pi))) (test "cos( 3/2pi)" 0.0 (cos (+ pi (/ pi 2)))) (test "acos(cos( 3/2pi))" (/ pi 2) (acos (cos (+ pi (/ pi 2))))) (test "cos( 4/3pi)" -0.5 (cos (+ pi (/ pi 3)))) (test "acos(cos( 4/3pi))" (* 2 (/ pi 3)) (acos (cos (+ pi (/ pi 3))))) (test "cos( 5/4pi)" -0.7071067811865476 (cos (+ pi (/ pi 4)))) (test "acos(cos( 5/4pi))" (* 3 (/ pi 4)) (acos (cos (+ pi (/ pi 4))))) (test "cos( 2pi)" 1.0 (cos (* 2 pi))) (test "acos(cos( 2pi))" 0 (acos (cos (* 2 pi)))) (test "acos(pi)" 0.0+1.81152627246085i (acos pi)) (test "acos(+inf)" -nan.0 (acos +inf.0)) (test "asin(-inf)" -nan.0 (asin -inf.0)) (test "asin()" -nan.0 (asin -1e100)) (test "sin(-1/3pi)" -0.8660254037844386 (sin (- (/ pi 3)))) (test "asin(sin(-1/3pi))" (- (/ pi 3)) (asin (sin (- (/ pi 3))))) (test "sin(-1/4pi)" -0.7071067811865476 (sin (- (/ pi 4)))) (test "asin(sin(-1/4pi))" (- (/ pi 4)) (asin (sin (- (/ pi 4))))) (test "sin(-1/2pi)" -1.0 (sin (- (/ pi 2)))) (test "asin(sin(-1/2pi))" (- (/ pi 2)) (asin (sin (- (/ pi 2))))) (test "sin(-pi)" 0.0 (sin (- pi))) (test "asin(sin(-pi))" 0.0 (asin (sin (- pi)))) (test "sin(0)" 0.0 (sin 0.0)) (test "asin(sin(0))" 0.0 (asin (sin 0.0))) (test "sin( 1/4pi)" 0.7071067811865476 (sin (/ pi 4))) (test "asin(sin( 1/4pi))" (/ pi 4) (asin (sin (/ pi 4)))) (test "sin( 1/3pi)" 0.8660254037844386 (sin (/ pi 3))) (test "asin(sin( 1/3pi))" (/ pi 3) (asin (sin (/ pi 3)))) (test "sin( 1/2pi)" 1.0 (sin (/ pi 2))) (test "asin(sin( 1/2pi))" (/ pi 2) (asin (sin (/ pi 2)))) (test "sin( 2/3pi)" 0.8660254037844386 (sin (/ (* 2 pi) 3))) (test "asin(sin( 2/3pi))" (/ pi 3) (asin (sin (/ (* 2 pi) 3)))) (test "sin( 3/4pi)" 0.7071067811865476 (sin (* (/ pi 4) 3))) (test "asin(sin( 3/4pi))" (/ pi 4) (asin (sin (* (/ pi 4) 3)))) (test "sin( pi)" 0.0 (sin pi)) (test "asin(sin( pi))" 0.0 (asin (sin pi))) (test "sin( 3/2pi)" -1.0 (sin (+ pi (/ pi 2)))) (test "asin(sin( 3/2pi))" (- (/ pi 2)) (asin (sin (+ pi (/ pi 2))))) (test "sin( 4/3pi)" -0.8660254037844386 (sin (+ pi (/ pi 3)))) (test "asin(sin( 4/3pi))" (- (/ pi 3)) (asin (sin (+ pi (/ pi 3))))) (test "sin( 5/4pi)" -0.7071067811865476 (sin (+ pi (/ pi 4)))) (test "asin(sin( 5/4pi))" (- (/ pi 4)) (asin (sin (+ pi (/ pi 4))))) (test "sin( 2pi)" 0.0 (sin (* 2 pi))) (test "asin(sin( 2pi))" 0.0 (asin (sin (* 2 pi)))) (test "asin(pi)" 1.57079632679490-1.81152627246085i (asin pi)) (test "asin(+inf)" -nan.0 (asin +inf.0)) (test "atan(-inf)" (- (/ pi 2)) (atan -inf.0)) (test "atan()" (- (/ pi 2)) (atan -1e100)) (test "tan(-1/3pi)" -1.7320508075688773 (tan (- (/ pi 3)))) (test "atan(tan(-1/3pi))" (- (/ pi 3)) (atan (tan (- (/ pi 3))))) (test "tan(-1/4pi)" -1.0 (tan (- (/ pi 4)))) (test "atan(tan(-1/4pi))" (- (/ pi 4)) (atan (tan (- (/ pi 4))))) ;; NOTE: tan(-(/ pi 2)) should be -inf(?), but isn't. Is that a bug? (test "tan(-pi)" 0.0 (tan (- pi))) (test "atan(tan(-pi))" 0.0 (atan (tan (- pi)))) (test "tan(0)" 0.0 (tan 0.0)) (test "atan(tan(0))" 0.0 (atan (tan 0.0))) (test "tan( 1/4pi)" 1.0 (tan (/ pi 4))) (test "atan(tan( 1/4pi))" (/ pi 4) (atan (tan (/ pi 4)))) (test "tan( 1/3pi)" 1.7320508075688773 (tan (/ pi 3))) (test "atan(tan( 1/3pi))" (/ pi 3) (atan (tan (/ pi 3)))) (test "tan( 2/3pi)" -1.7320508075688773 (tan (/ (* 2 pi) 3))) (test "atan(tan( 2/3pi))" (- (/ pi 3)) (atan (tan (/ (* 2 pi) 3)))) (test "tan( 3/4pi)" -1.0 (tan (* (/ pi 4) 3))) (test "atan(tan( 3/4pi))" (- (/ pi 4)) (atan (tan (* (/ pi 4) 3)))) (test "tan( pi)" 0.0 (tan pi)) (test "atan(tan( pi))" 0.0 (atan (tan pi))) (test "tan( 4/3pi)" 1.7320508075688773 (tan (+ pi (/ pi 3)))) (test "atan(tan( 4/3pi))" (/ pi 3) (atan (tan (+ pi (/ pi 3))))) (test "tan( 5/4pi)" 1.0 (tan (+ pi (/ pi 4)))) (test "atan(tan( 5/4pi))" (/ pi 4) (atan (tan (+ pi (/ pi 4))))) (test "tan( 2pi)" 0.0 (tan (* 2 pi))) (test "atan(tan( 2pi))" 0.0 (atan (tan (* 2 pi)))) (test "atan(pi)" (/ pi 2) (atan 1e100)) (test "atan(+inf)" (/ pi 2) (atan +inf.0)) (test "atan2(3, tan(pi))" (/ pi 2) (atan 3 (tan pi))) (test "atan2(3, -tan(pi))" (/ pi 2) (atan 3 (- (tan pi)))) (test "atan2(-3, tan(pi))" (- (/ pi 2)) (atan -3 (tan pi))) (test "atan2(-3, -tan(pi))" (- (/ pi 2)) (atan -3 (- (tan pi)))) ;; Equivalence described in R5RS (test "atan2(1, 2) = angle(2+i)" (atan 1 2) (angle (make-rectangular 2 1))) (test "atan2(1, b1) = angle(2+i)" (atan 1 b1) (angle (make-rectangular b1 1))) (test "atan2(b1, 1) = angle(2+i)" (atan b1 1) (angle (make-rectangular 1 b1))) (test "atan2(-0.1, 3.2) = angle(3.2-0.1i)" (atan -0.1 3.2) (angle (make-rectangular 3.2 -0.1))) ) ;; Cross-checked against Gauche and Scheme48's output (test-group "compnums" (test "cos(0.0+1.0i)" 1.5430806348152437 (cos (make-rectangular 0.0 1.0))) (test "acos(cos(0.0+1.0i))" 0.0+1.0i (acos (cos (make-rectangular 0.0 1.0)))) (test "cos(0.0-1.0i)" 1.5430806348152437 (cos (make-rectangular 0.0 -1.0))) (test "acos(cos(0.0-1.0i))" 0.0+1.0i (acos (cos (make-rectangular 0.0 -1.0)))) (test "cos(0.0+3.0i)" 10.067661995777765 (cos (make-rectangular 0.0 3.0))) (test "acos(cos(0.0+3.0i))" 0.0+3.0i (acos (cos (make-rectangular 0.0 3.0)))) (test "cos(0.0-3.0i)" 10.067661995777765 (cos (make-rectangular 0.0 -3.0))) (test "acos(cos(0.0-3.0i))" 0.0+3.0i (acos (cos (make-rectangular 0.0 -3.0)))) (test "cos(0.5+0.5i)" (make-rectangular 0.9895848833999199 -0.24982639750046154) (cos (make-rectangular 0.5 0.5))) (test "acos(cos(0.5+0.5i))" (make-rectangular 0.5 0.5) (acos (cos (make-rectangular 0.5 0.5)))) (test "cos(0.5-0.5i)" (make-rectangular 0.9895848833999199 0.24982639750046154) (cos (make-rectangular 0.5 -0.5))) (test "acos(cos(0.5-0.5i))" (make-rectangular 0.5 -0.5) (acos (cos (make-rectangular 0.5 -0.5)))) (test "cos(-0.5-0.5i)" (make-rectangular 0.9895848833999199 -0.24982639750046154) (cos (make-rectangular -0.5 -0.5))) (test "acos(cos(-0.5-0.5i))" (make-rectangular 0.5 0.5) (acos (cos (make-rectangular -0.5 -0.5)))) (test "cos(-0.5+0.5i)" (make-rectangular 0.9895848833999199 0.24982639750046154) (cos (make-rectangular -0.5 0.5))) (test "acos(cos(-0.5+0.5i))" (make-rectangular 0.5 -0.5) (acos (cos (make-rectangular -0.5 0.5)))) (test "cos(-1.0+1.0i)" (make-rectangular 0.8337300251311491 0.9888977057628651) (cos (make-rectangular -1.0 1.0))) (test "acos(cos(-1.0+1.0i))" (make-rectangular 1.0 -1.0) (acos (cos (make-rectangular -1.0 1.0)))) (test "cos(-1.0-1.0i)" (make-rectangular 0.8337300251311491 -0.9888977057628651) (cos (make-rectangular -1.0 -1.0))) (test "acos(cos(-1.0-1.0i))" (make-rectangular 1.0 1.0) (acos (cos (make-rectangular -1.0 -1.0)))) (test "cos(1.0-1.0i)" (make-rectangular 0.8337300251311491 0.9888977057628651) (cos (make-rectangular 1.0 -1.0))) (test "acos(cos(1.0-1.0i))" (make-rectangular 1.0 -1.0) (acos (cos (make-rectangular 1.0 -1.0)))) (test "cos(1.0+1.0i)" (make-rectangular 0.8337300251311491 -0.9888977057628651) (cos (make-rectangular 1.0 1.0))) (test "acos(cos(1.0+1.0i))" (make-rectangular 1.0 1.0) (acos (cos (make-rectangular 1.0 1.0)))) (test "cos(2.0+3.0i)" (make-rectangular -4.189625690968807 -9.109227893755337) (cos (make-rectangular 2.0 3.0))) (test "acos(cos(2.0+3.0i))" (make-rectangular 2.0 3.0) (acos (cos (make-rectangular 2.0 3.0)))) (test "cos(-2.0+3.0i)" (make-rectangular -4.189625690968807 9.109227893755337) (cos (make-rectangular -2.0 3.0))) (test "acos(cos(-2.0+3.0i))" (make-rectangular 2.0 -3.0) (acos (cos (make-rectangular -2.0 3.0)))) (test "cos(-2.0-3.0i)" (make-rectangular -4.189625690968807 -9.109227893755337) (cos (make-rectangular -2.0 -3.0))) (test "acos(cos(-2.0-3.0i))" (make-rectangular 2.0 3.0) (acos (cos (make-rectangular -2.0 -3.0)))) (test "cos(2.0-3.0i)" (make-rectangular -4.189625690968807 9.109227893755337) (cos (make-rectangular 2.0 -3.0))) (test "acos(cos(2.0-3.0i))" (make-rectangular 2.0 -3.0) (acos (cos (make-rectangular 2.0 -3.0)))) ;; Specialization check (test "cos(acos(2.0-3.0i))" (make-rectangular 2.0 -3.0) (cos (acos (make-rectangular 2.0 -3.0)))) (test "sin(0.0+1.0i)" (make-rectangular 0.0 1.1752011936438014) (sin (make-rectangular 0.0 1.0))) (test "asin(sin(0.0+1.0i))" (make-rectangular 0.0 1.0) (asin (sin (make-rectangular 0.0 1.0)))) (test "sin(0.0-1.0i)" (make-rectangular 0.0 -1.1752011936438014) (sin (make-rectangular 0.0 -1.0))) (test "asin(sin(0.0-1.0i))" (make-rectangular 0.0 -1.0) (asin (sin (make-rectangular 0.0 -1.0)))) (test "sin(0.0+3.0i)" (make-rectangular 0.0 10.017874927409903) (sin (make-rectangular 0.0 3.0))) (test "asin(sin(0.0+3.0i))" (make-rectangular 0.0 3.0) (asin (sin (make-rectangular 0.0 3.0)))) (test "sin(0.0-3.0i)" (make-rectangular 0.0 -10.017874927409903) (sin (make-rectangular 0.0 -3.0))) (test "asin(sin(0.0-3.0i))" (make-rectangular 0.0 -3.0) (asin (sin (make-rectangular 0.0 -3.0)))) (test "sin(0.5+0.5i)" (make-rectangular 0.5406126857131534 0.4573041531842493) (sin (make-rectangular 0.5 0.5))) (test "asin(sin(0.5+0.5i))" (make-rectangular 0.5 0.5) (asin (sin (make-rectangular 0.5 0.5)))) (test "sin(0.5-0.5i)" (make-rectangular 0.5406126857131534 -0.4573041531842493) (sin (make-rectangular 0.5 -0.5))) (test "asin(sin(0.5-0.5i))" (make-rectangular 0.5 -0.5) (asin (sin (make-rectangular 0.5 -0.5)))) (test "sin(-0.5-0.5i)" (make-rectangular -0.5406126857131534 -0.4573041531842493) (sin (make-rectangular -0.5 -0.5))) (test "asin(sin(-0.5-0.5i))" (make-rectangular -0.5 -0.5) (asin (sin (make-rectangular -0.5 -0.5)))) (test "sin(-0.5+0.5i)" (make-rectangular -0.5406126857131534 +0.457304153184249) (sin (make-rectangular -0.5 0.5))) (test "asin(sin(-0.5+0.5i))" (make-rectangular -0.5 +0.5) (asin (sin (make-rectangular -0.5 0.5)))) (test "sin(-1.0+1.0i)" (make-rectangular -1.2984575814159773 0.6349639147847361) (sin (make-rectangular -1.0 1.0))) (test "asin(sin(-1.0+1.0i))" (make-rectangular -1.0 1.0) (asin (sin (make-rectangular -1.0 1.0)))) (test "sin(-1.0-1.0i)" (make-rectangular -1.2984575814159773 -0.6349639147847361) (sin (make-rectangular -1.0 -1.0))) (test "asin(sin(-1.0-1.0i))" (make-rectangular -1.0 -1.0) (asin (sin (make-rectangular -1.0 -1.0)))) (test "sin(1.0-1.0i)" (make-rectangular 1.2984575814159773 -0.6349639147847361) (sin (make-rectangular 1.0 -1.0))) (test "asin(sin(1.0-1.0i))" (make-rectangular 1.0 -1.0) (asin (sin (make-rectangular 1.0 -1.0)))) (test "sin(2.0+3.0i)" (make-rectangular 9.15449914691143 -4.168906959966565) (sin (make-rectangular 2.0 3.0))) (test "asin(sin(2.0+3.0i))" (make-rectangular 1.1415926535898042 -3.0) (asin (sin (make-rectangular 2.0 3.0)))) (test "sin(-2.0+3.0i)" (make-rectangular -9.15449914691143 -4.168906959966565) (sin (make-rectangular -2.0 3.0))) (test "asin(sin(-2.0+3.0i))" (make-rectangular -1.1415926535898042 -3.0) (asin (sin (make-rectangular -2.0 3.0)))) (test "sin(-2.0-3.0i)" (make-rectangular -9.15449914691143 4.168906959966565) (sin (make-rectangular -2.0 -3.0))) (test "asin(sin(-2.0-3.0i))" (make-rectangular -1.1415926535898042 3.0) (asin (sin (make-rectangular -2.0 -3.0)))) (test "sin(2.0-3.0i)" (make-rectangular 9.15449914691143 4.168906959966565) (sin (make-rectangular 2.0 -3.0))) (test "asin(sin(2.0-3.0i))" (make-rectangular 1.1415926535898042 3.0) (asin (sin (make-rectangular 2.0 -3.0)))) ;; Specialization check (test "sin(asin(1.1415926535898042+3.0i))" (make-rectangular 2.0 3.0) (sin (asin (make-rectangular 2.0 3.0)))) (test "tan(0.0+1.0i)" (make-rectangular 0.0 0.7615941559557649) (tan (make-rectangular 0.0 1.0))) (test "atan(tan(0.0+1.0i))" (make-rectangular 0.0 1.0) (atan (tan (make-rectangular 0.0 1.0)))) (test "tan(0.0-1.0i)" (make-rectangular 0.0 -0.7615941559557649) (tan (make-rectangular 0.0 -1.0))) (test "atan(tan(0.0-1.0i))" (make-rectangular 0.0 -1.0) (atan (tan (make-rectangular 0.0 -1.0)))) (test "tan(0.0+3.0i)" (make-rectangular 0.0 0.9950547536867306) (tan (make-rectangular 0.0 3.0))) (test "atan(tan(0.0+3.0i))" (make-rectangular 0.0 3.0) (atan (tan (make-rectangular 0.0 3.0)))) (test "tan(0.0-3.0i)" (make-rectangular 0.0 -0.9950547536867306) (tan (make-rectangular 0.0 -3.0))) (test "atan(tan(0.0-3.0i))" (make-rectangular 0.0 -3.0) (atan (tan (make-rectangular 0.0 -3.0)))) (test "tan(0.5+0.5i)" (make-rectangular 0.4038964553160257 0.5640831412674985) (tan (make-rectangular 0.5 0.5))) (test "atan(tan(0.5+0.5i))" (make-rectangular 0.5 0.5) (atan (tan (make-rectangular 0.5 0.5)))) (test "tan(0.5-0.5i)" (make-rectangular 0.4038964553160257 -0.5640831412674985) (tan (make-rectangular 0.5 -0.5))) (test "atan(tan(0.5-0.5i))" (make-rectangular 0.5 -0.5) (atan (tan (make-rectangular 0.5 -0.5)))) (test "tan(-0.5-0.5i)" (make-rectangular -0.4038964553160257 -0.5640831412674985) (tan (make-rectangular -0.5 -0.5))) (test "atan(tan(-0.5-0.5i))" (make-rectangular -0.5 -0.5) (atan (tan (make-rectangular -0.5 -0.5)))) (test "tan(-0.5+0.5i)" (make-rectangular -0.4038964553160257 0.5640831412674985) (tan (make-rectangular -0.5 0.5))) (test "atan(tan(-0.5+0.5i))" (make-rectangular -0.5 0.5) (atan (tan (make-rectangular -0.5 0.5)))) (test "tan(-1.0+1.0i)" (make-rectangular -0.27175258531951174 1.0839233273386948) (tan (make-rectangular -1.0 1.0))) (test "atan(tan(-1.0+1.0i))" (make-rectangular -1.0 1.0) (atan (tan (make-rectangular -1.0 1.0)))) (test "tan(-1.0-1.0i)" (make-rectangular -0.27175258531951174 -1.0839233273386948) (tan (make-rectangular -1.0 -1.0))) (test "atan(tan(-1.0-1.0i))" (make-rectangular -1.0 -1.0) (atan (tan (make-rectangular -1.0 -1.0)))) (test "tan(1.0-1.0i)" (make-rectangular 0.27175258531951174 -1.0839233273386948) (tan (make-rectangular 1.0 -1.0))) (test "atan(tan(1.0-1.0i))" (make-rectangular 1.0 -1.0) (atan (tan (make-rectangular 1.0 -1.0)))) (test "tan(2.0+3.0i)" (make-rectangular -0.0037640256415040815 1.0032386273536098) (tan (make-rectangular 2.0 3.0))) (test "atan(tan(2.0+3.0i))" (make-rectangular -1.1415926535898042 3.0) (atan (tan (make-rectangular 2.0 3.0)))) (test "tan(-2.0+3.0i)" (make-rectangular 0.0037640256415040815 1.0032386273536098) (tan (make-rectangular -2.0 3.0))) (test "atan(tan(-2.0+3.0i))" (make-rectangular 1.1415926535898042 3.0) (atan (tan (make-rectangular -2.0 3.0)))) (test "tan(-2.0-3.0i)" (make-rectangular 0.0037640256415040815 -1.0032386273536098) (tan (make-rectangular -2.0 -3.0))) (test "atan(tan(-2.0-3.0i))" (make-rectangular 1.1415926535898042 -3.0) (atan (tan (make-rectangular -2.0 -3.0)))) (test "tan(2.0-3.0i)" (make-rectangular -0.0037640256415040815 -1.0032386273536098) (tan (make-rectangular 2.0 -3.0))) (test "atan(tan(2.0-3.0i))" (make-rectangular -1.1415926535898042 -3.0) (atan (tan (make-rectangular 2.0 -3.0)))) ;; Specialization check (test "tan(atan(2.0-3.0i))" (make-rectangular 2.0 -3.0) (tan (atan (make-rectangular 2.0 -3.0)))) ) ;; This is just a handful to determine that we're able to accept these. ;; Maybe determine better values to test with? (test-group "bignums" (test "acos()" -nan.0 (acos (- b1))) ;; These are bogus (maybe the negative ones too!), but I don't want to ;; "fix" them by copying the output and assume it's alright. #;(test "acos()" +nan.0 (acos b1)) (test "asin()" -nan.0 (asin (- b1))) #;(test "asin()" +nan.0 (asin b1)) (test "atan()" (- (/ pi 2)) (atan (- b1))) (test "atan()" (/ pi 2) (atan b1))) ;; This should probably be enough; we're only testing conversion to flonums ;; and specialization. The actual functionality of cos is checked above. (test-group "fixnums" (test "cos(0)" 1.0 (cos 0)) (test "acos(0)" (/ pi 2) (acos 0)) (test "cos(1)" (cos 1.0) (cos 1)) (test "acos(1)" 0.0 (acos 1)) (test "cos(-1)" (cos -1.0) (cos -1)) (test "acos(-1)" pi (acos -1)) (test "acos(-2)" (make-rectangular pi -1.31695789692482) (acos -2)) (test "acos(2)" 0.0+1.31695789692482i (acos 2)) (test "asin(1)" (/ pi 2) (asin 1)) (test "asin(-1)" (/ pi -2) (asin -1)) (test "asin(2)" (make-rectangular (/ pi 2) -1.31695789692482) (asin 2)) (test "asin(-2)" (make-rectangular (/ pi -2) 1.31695789692482) (asin -2))) (test-group "ratnums" (test "acos()" -nan.0 (acos (/ -999999999 2))) (test "cos(-1/3pi)" 0.5 (cos (- (/ ratpi 3)))) (test "acos(cos(-1/3pi))" (/ pi 3) (acos (cos (- (/ ratpi 3))))) (test "cos(-1/4pi)" 0.7071067811865476 (cos (- (/ ratpi 4)))) (test "acos(cos(-1/4pi))" (/ pi 4) (acos (cos (- (/ ratpi 4))))) (test "cos(-1/2pi)" 0.0 (cos (- (/ ratpi 2)))) (test "acos(cos(-1/2pi))" (/ pi 2) (acos (cos (- (/ ratpi 2))))) (test "cos(-pi)" -1.0 (cos (- ratpi))) (test "acos(cos(-pi))" pi (acos (cos (- ratpi)))) (test "cos(0)" 1.0 (cos 0.0)) (test "acos(cos(0))" 0.0 (acos (cos 0.0))) (test "cos( 1/4pi)" 0.7071067811865476 (cos (/ ratpi 4))) (test "acos(cos( 1/4pi))" (/ pi 4) (acos (cos (/ ratpi 4)))) (test "cos( 1/3pi)" 0.5 (cos (/ ratpi 3))) (test "acos(cos( 1/3pi))" (/ pi 3) (acos (cos (/ ratpi 3)))) (test "cos( 1/2pi)" 0.0 (cos (/ ratpi 2))) (test "acos(cos( 1/2pi))" (/ pi 2) (acos (cos (/ ratpi 2)))) (test "cos( 2/3pi)" -0.5 (cos (/ (* 2 ratpi) 3))) (test "acos(cos( 2/3pi))" (/ (* 2 pi) 3) (acos (cos (/ (* 2 ratpi) 3)))) (test "cos( 3/4pi)" -0.7071067811865476 (cos (* (/ ratpi 4) 3))) (test "acos(cos( 3/4pi))" (* (/ pi 4) 3) (acos (cos (* (/ ratpi 4) 3)))) (test "cos( pi)" -1.0 (cos ratpi)) (test "acos(cos( pi))" pi (acos (cos ratpi))) (test "cos( 3/2pi)" 0.0 (cos (+ ratpi (/ ratpi 2)))) (test "acos(cos( 3/2pi))" (/ pi 2) (acos (cos (+ ratpi (/ ratpi 2))))) (test "cos( 4/3pi)" -0.5 (cos (+ ratpi (/ ratpi 3)))) (test "acos(cos( 4/3pi))" (* 2 (/ pi 3)) (acos (cos (+ ratpi (/ ratpi 3))))) (test "cos( 5/4pi)" -0.7071067811865476 (cos (+ ratpi (/ ratpi 4)))) (test "acos(cos( 5/4pi))" (* 3 (/ pi 4)) (acos (cos (+ ratpi (/ ratpi 4))))) (test "cos( 2pi)" 1.0 (cos (* 2 pi))) (test "acos(cos( 2pi))" 0 (acos (cos (* 2 ratpi)))) (test "sin(-1/3pi)" -0.8660254037844386 (sin (- (/ ratpi 3)))) (test "asin(sin(-1/3pi))" (- (/ pi 3)) (asin (sin (- (/ ratpi 3))))) (test "sin(-1/4pi)" -0.7071067811865476 (sin (- (/ ratpi 4)))) (test "asin(sin(-1/4pi))" (- (/ pi 4)) (asin (sin (- (/ ratpi 4))))) (test "sin(-1/2pi)" -1.0 (sin (- (/ ratpi 2)))) (test "asin(sin(-1/2pi))" (- (/ pi 2)) (asin (sin (- (/ ratpi 2))))) (test "sin(-pi)" 0.0 (sin (- ratpi))) (test "asin(sin(-pi))" 0.0 (asin (sin (- ratpi)))) (test "sin(0)" 0.0 (sin 0.0)) (test "asin(sin(0))" 0.0 (asin (sin 0.0))) (test "sin( 1/4pi)" 0.7071067811865476 (sin (/ ratpi 4))) (test "asin(sin( 1/4pi))" (/ pi 4) (asin (sin (/ ratpi 4)))) (test "sin( 1/3pi)" 0.8660254037844386 (sin (/ ratpi 3))) (test "asin(sin( 1/3pi))" (/ pi 3) (asin (sin (/ ratpi 3)))) (test "sin( 1/2pi)" 1.0 (sin (/ ratpi 2))) (test "asin(sin( 1/2pi))" (/ pi 2) (asin (sin (/ ratpi 2)))) (test "sin( 2/3pi)" 0.8660254037844386 (sin (/ (* 2 ratpi) 3))) (test "asin(sin( 2/3pi))" (/ pi 3) (asin (sin (/ (* 2 ratpi) 3)))) (test "sin( 3/4pi)" 0.7071067811865476 (sin (* (/ ratpi 4) 3))) (test "asin(sin( 3/4pi))" (/ pi 4) (asin (sin (* (/ ratpi 4) 3)))) (test "sin( pi)" 0.0 (sin ratpi)) (test "asin(sin( pi))" 0.0 (asin (sin ratpi))) (test "sin( 3/2pi)" -1.0 (sin (+ ratpi (/ ratpi 2)))) (test "asin(sin( 3/2pi))" (- (/ pi 2)) (asin (sin (+ ratpi (/ ratpi 2))))) (test "sin( 4/3pi)" -0.8660254037844386 (sin (+ ratpi (/ ratpi 3)))) (test "asin(sin( 4/3pi))" (- (/ pi 3)) (asin (sin (+ ratpi (/ ratpi 3))))) (test "sin( 5/4pi)" -0.7071067811865476 (sin (+ ratpi (/ ratpi 4)))) (test "asin(sin( 5/4pi))" (- (/ pi 4)) (asin (sin (+ ratpi (/ ratpi 4))))) (test "sin( 2pi)" 0.0 (sin (* 2 ratpi))) (test "asin(sin( 2pi))" 0.0 (asin (sin (* 2 ratpi)))) (test "tan(-1/3pi)" -1.7320508075688773 (tan (- (/ ratpi 3)))) (test "atan(tan(-1/3pi))" (- (/ pi 3)) (atan (tan (- (/ ratpi 3))))) (test "tan(-1/4pi)" -1.0 (tan (- (/ ratpi 4)))) (test "atan(tan(-1/4pi))" (- (/ pi 4)) (atan (tan (- (/ ratpi 4))))) ;; NOTE: tan(-(/ pi 2)) should be -inf(?), but isn't. Is that a bug? (test "tan(-pi)" 0.0 (tan (- ratpi))) (test "atan(tan(-pi))" 0.0 (atan (tan (- ratpi)))) (test "tan(0)" 0.0 (tan 0.0)) (test "atan(tan(0))" 0.0 (atan (tan 0.0))) (test "tan( 1/4pi)" 1.0 (tan (/ ratpi 4))) (test "atan(tan( 1/4pi))" (/ pi 4) (atan (tan (/ ratpi 4)))) (test "tan( 1/3pi)" 1.7320508075688773 (tan (/ ratpi 3))) (test "atan(tan( 1/3pi))" (/ pi 3) (atan (tan (/ ratpi 3)))) (test "tan( 2/3pi)" -1.7320508075688773 (tan (/ (* 2 ratpi) 3))) (test "atan(tan( 2/3pi))" (- (/ pi 3)) (atan (tan (/ (* 2 ratpi) 3)))) (test "tan( 3/4pi)" -1.0 (tan (* (/ ratpi 4) 3))) (test "atan(tan( 3/4pi))" (- (/ pi 4)) (atan (tan (* (/ ratpi 4) 3)))) (test "tan( pi)" 0.0 (tan ratpi)) (test "atan(tan( pi))" 0.0 (atan (tan ratpi))) (test "tan( 4/3pi)" 1.7320508075688773 (tan (+ ratpi (/ ratpi 3)))) (test "atan(tan( 4/3pi))" (/ pi 3) (atan (tan (+ ratpi (/ ratpi 3))))) (test "tan( 5/4pi)" 1.0 (tan (+ ratpi (/ ratpi 4)))) (test "atan(tan( 5/4pi))" (/ pi 4) (atan (tan (+ ratpi (/ ratpi 4))))) (test "tan( 2pi)" 0.0 (tan (* 2 ratpi))) (test "atan(tan( 2i))" 0.0 (atan (tan (* 2 ratpi)))) (test "atan2(3, tan(pi))" (/ pi 2) (atan 3 (tan ratpi))) (test "atan2(3, -tan(pi))" (/ pi 2) (atan 3 (- (tan ratpi)))) (test "atan2(-3, tan(pi))" (- (/ pi 2)) (atan -3 (tan ratpi))) (test "atan2(-3, -tan(pi))" (- (/ pi 2)) (atan -3 (- (tan ratpi))))))) (test-end) ;(unless (zero? (test-failure-count)) (exit 1))