tests/mz-tests/number.rkt
#lang s-exp "../../lang/base.rkt"

(require "testing.rkt")

(Section 'numbers)

(test #f number? 'a)
(test #f complex? 'a)
(test #f real? 'a)
(test #f rational? 'a)
(test #f integer? 'a)

(test #t number? 3)
(test #t complex? 3)
(test #t real? 3)
(test #t rational? 3)
(test #t integer? 3)

(test #t number? 3.0)
(test #t complex? 3.0)
(test #t real? 3.0)
(test #t rational? 3.0)
(test #t integer? 3.0)

(test #t number? 3.1)
(test #t complex? 3.1)
(test #t real? 3.1)
(test #t rational? 3.1)
(test #f integer? 3.1)

(test #t number? 3/2)
(test #t complex? 3/2)
(test #t real? 3/2)
(test #t rational? 3/2)
(test #f integer? 3/2)

(test #t number? 3+i)
(test #t complex? 3+i)
(test #f real? 3+i)
(test #f rational? 3+i)
(test #f integer? 3+i)

(test #t number? 3.0+0i)
(test #t complex? 3.0+0i)
(test #t real? 3.0+0i)
(test #t rational? 3.0+0i)
(test #t integer? 3.0+0i)

(test #t number? 3.0+0.0i)
(test #t complex? 3.0+0.0i)
(test #f real? 3.0+0.0i)
(test #f rational? 3.0+0.0i)
(test #f integer? 3.0+0.0i)

(test #t number? 3.1+0.0i)
(test #t complex? 3.1+0.0i)
(test #f real? 3.1+0.0i)
(test #f rational? 3.1+0.0i)
(test #f integer? 3.1+0.0i)

(test #t exact? 3)
(test #t exact? 3/4)
(test #f exact? 3.0)
(test #t exact? (expt 2 100))
(test #t exact? 3+4i)
(test #f exact? 3.0+4i)

(test #f inexact? 3)
(test #f inexact? 3/4)
(test #t inexact? 3.0)
(test #f inexact? (expt 2 100))
(test #f inexact? 3+4i)
(test #t inexact? 3.0+4i)
(test #t inexact? 0+4.0i)
(test #t inexact? 4+0.i)

(test #t complex? -4.242154731064108e-5-6.865001427422244e-5i)
(test #f exact? -4.242154731064108e-5-6.865001427422244e-5i)
(test #t inexact? -4.242154731064108e-5-6.865001427422244e-5i)

(test #t complex? -4.242154731064108f-5-6.865001427422244f-5i)
(test #f exact? -4.242154731064108f-5-6.865001427422244f-5i)
(test #t inexact? -4.242154731064108f-5-6.865001427422244f-5i)

(test #t number? +inf.0)
(test #t complex? +inf.0)
(test #t real? +inf.0)
(test #f rational? +inf.0)
(test #f integer? +inf.0)

(test #t number? -inf.0)
(test #t complex? -inf.0)
(test #t real? -inf.0)
(test #f rational? -inf.0)
(test #f integer? -inf.0)

(test #t number? +nan.0)
(test #t complex? +nan.0)
(test #t real? +nan.0)
(test #f rational? +nan.0)
(test #f integer? +nan.0)

(arity-test inexact? 1 1)
(arity-test number? 1 1)
(arity-test complex? 1 1)
(arity-test real? 1 1)
(arity-test rational? 1 1)
(arity-test integer? 1 1)
(arity-test exact? 1 1)
(arity-test inexact? 1 1)

(err/rt-test (exact? 'a))
(err/rt-test (inexact? 'a))

(test "+inf.0" number->string +inf.0)
(test "-inf.0" number->string -inf.0)
(test "+nan.0" number->string +nan.0)
(test "+nan.0" number->string +nan.0)

(map (lambda (n)
       ;; test that fresh strings are generated:
       (let ([n1 (number->string n)]
	     [n2 (number->string n)])
	 (string-set! n1 0 #\?)
	 (test n2 number->string n)
	 (test n1 string-append "?" (substring n2 1 (string-length n2)))))
     '(+inf.0 -inf.0 +nan.0 -nan.0 0.0 -0.0 0 1/2 3.4 1+2i))

(test #t = 0.0 -0.0)
(test #f eqv? 0.0 -0.0)
(test #f equal? 0.0 -0.0)
(test #f eqv? -0.0 0.0)
(test #t eqv? 0.0 0.0)
(test #t eqv? -0.0 -0.0)

(test #t = 22 22 22)
(test #t = 22 22)
(test #f = 34 34 35)
(test #f = 34 35)
(test #t > 3 -6246)
(test #f > 9 9 -2424)
(test #t >= 3 -4 -6246)
(test #t >= 9 9)
(test #f >= 8 9)
(test #t < -1 2 3 4 5 6 7 8)
(test #f < -1 2 3 4 4 5 6 7)
(test #t <= -1 2 3 4 5 6 7 8)
(test #t <= -1 2 3 4 4 5 6 7)
(test #f < 1 3 2)
(test #f >= 1 3 2)

(define (test-compare lo m hi) ; all positive!
  (define -lo (- lo))
  (define -m (- m))
  (define -hi (- hi))

  (define (test-lh l h)
    (test #f > l h)
    (test #t < l h)
    (test #f = l h)
    (test #f >= l h)
    (test #t <= l h))

  (define (test-hl h l)
    (test #t > h l)
    (test #f < h l)
    (test #f = h l)
    (test #t >= h l)
    (test #f <= h l))

  (define (test-zero z)
    (test-hl m z)
    (test-lh -m z)
    (test-hl z -m)
    (test-lh z m))

  (test-lh m hi)
  (test-hl -m -hi)

  (test #f > m m)
  (test #f < m m)
  (test #t = m m)
  (test #t >= m m)
  (test #t <= m m)

  (test-hl m -m)
  (test-lh -m m)

  (test-hl m lo)
  (test-lh -m -lo)

  (test-zero 0)
  (test-zero 0.0))
  
(test-compare 0.5 1.2 2.3)
(test-compare 2/5 1/2 2/3)
(test-compare 1/4 1/3 1/2) ; same numerator
(test-compare 3/10 7/10 9/10) ; same denominator
(test-compare 2/500000000000000000000000000 1/200000000000000000000000000 2/300000000000000000000000000) ; bignums
(test #t = 1/2 2/4)
(test #f = 2/3 2/5)
(test #f = 2/3 2/500000000000000000000000000)

(test-compare 0.5 6/5 2.3)
(test-compare 1 11922615739/10210200 3000)
(test-compare 1.0 11922615739/10210200 3000.0)

(err/rt-test (< 1 2.3+0.0i))
(err/rt-test (> 1 2.3+0.0i))
(err/rt-test (<= 1 2.3+0.0i))
(err/rt-test (>= 1 2.3+0.0i))
(err/rt-test (< 2.3+0.0i 1))
(err/rt-test (> 2.3+0.0i 1))
(err/rt-test (<= 2.3+0.0i 1))
(err/rt-test (>= 2.3+0.0i 1))

(test #f > 0 (/ 1 (expt 2 400)))

(test #t < 0.5 2/3)
(test #f < 2/3 0.5)
(test #t = 0.5 1/2)
(test #t = +0.5i +1/2i)
(test #f = +0.5i 1+1/2i)
(test #t = 1 1.0+0i)
(test #t = 1 1.0+0.0i)
(test #f eqv? 1.0 1.0+0.0i)
(test #f eqv? 1.0-0.0i 1.0+0.0i)
(test #f eqv? 1.0+0.0i 1.0-0.0i)
(test #t eqv? 1.0+0.0i 1.0+0.0i)
(test #t eqv? 1.0-0.0i 1.0-0.0i)

(test #f = 1+2i 2+i)

;; Test transitivity in mixed exact--inexact settings
;; (Thanks again to Aubrey Jaffer for the starting point.)
(define (test-trans expect op nop a b c)
  ;; Make sure the tests check what we want to check:
  (test #t = (exact->inexact a) b)
  (test #t = (exact->inexact c) b)
  (test #t = (exact->inexact (- a)) (- b))
  (test #t = (exact->inexact (- c)) (- b))
  ;; The real tests:
  (test expect op a b)
  (test expect op b c)
  (test expect op a b c)
  (test expect nop (- a) (- b))
  (test expect nop (- b) (- c))
  (test expect nop (- a) (- b) (- c))
  (test expect nop c b)
  (test expect nop b a)
  (test expect nop c b a)
  (test expect op (- c) (- b))
  (test expect op (- b) (- a))
  (test expect op (- c) (- b) (- a)))
(test-trans #t < >= 1237940039285380274899124223 1.2379400392853803e+27 1237940039285380274899124225)
(test-trans #t < >= 3713820117856140824697372668/3 1.2379400392853803e+27 3713820117856140824697372676/3)
(test-trans #f > <= 1237940039285380274899124223 1.2379400392853803e+27 1237940039285380274899124225)
(test-trans #f > <= 3713820117856140824697372668/3 1.2379400392853803e+27 3713820117856140824697372676/3)
(test-trans #f = = 1237940039285380274899124223 1.2379400392853803e+27 1237940039285380274899124225)
(test-trans #f = = 3713820117856140824697372668/3 1.2379400392853803e+27 3713820117856140824697372676/3)
(test-trans #t <= > 1237940039285380274899124223 1.2379400392853803e+27 1237940039285380274899124225)
(test-trans #t <= > 3713820117856140824697372668/3 1.2379400392853803e+27 3713820117856140824697372676/3)
(test-trans #f >= < 1237940039285380274899124223 1.2379400392853803e+27 1237940039285380274899124225)
(test-trans #f >= < 3713820117856140824697372668/3 1.2379400392853803e+27 3713820117856140824697372676/3)

(define (test-nan.0 f . args)
  (apply test +nan.0 f args))

(define (test-i-nan.0 f . args)
  (apply test (make-rectangular +nan.0 +nan.0) f args))

(define (test-nan c)
  (test #f < +nan.0 c)
  (test #f > +nan.0 c)
  (test #f = +nan.0 c)
  (test #f <= +nan.0 c)
  (test #f >= +nan.0 c))
(test-nan 0)
(test-nan 0.0)
(test-nan 0.3)
(test-nan +nan.0)
(test-nan +inf.0)
(test-nan -inf.0)
(test-nan (expt 2 90))
(err/rt-test (test-nan 0.3+0.0i))
(test #f = +nan.0 1+2i)
(test #f = +nan.0 (make-rectangular +inf.0 -inf.0))

(test-compare 999999999999 1000000000000 1000000000001)
(define big-num (expt 2 1500))
(test-compare (sub1 big-num) big-num (add1 big-num))
(test-compare 1.0 (expt 10 100) 1e200)

(define (inf-zero-test inf rx negnot)
  (let ([inf-test-x
	 (lambda (r v)
	   (test r < v inf)
	   (test (not r) > v inf)
	   (test r <= v inf)
	   (test (not r) >= v inf)
	   
	   (test (not r) < inf v)
	   (test r > inf v)
	   (test (not r) <= inf v)
	   (test r >= inf v))])
    (inf-test-x rx 5)
    (inf-test-x (negnot rx) -5)
    (inf-test-x rx big-num)
    (inf-test-x (negnot rx) (- big-num))
    (inf-test-x rx (/ big-num 3))
    (inf-test-x (negnot rx) (/ (- big-num) 3))
    (inf-test-x rx (/ 1 big-num))
    (inf-test-x (negnot rx) (/ 1 (- big-num)))))
(inf-zero-test +inf.0 #t (lambda (x) x))
(inf-zero-test -inf.0 #f (lambda (x) x))
(inf-zero-test 0.0 #f not)

(err/rt-test (= 1 'a))
(err/rt-test (= 1 1 'a))
(err/rt-test (= 1 2 'a))
(err/rt-test (= 'a 1))
(err/rt-test (> 1 'a))
(err/rt-test (> 1 0 'a))
(err/rt-test (> 1 2 'a))
(err/rt-test (> 'a 1))
(err/rt-test (> 0.5+0.1i 1))
(err/rt-test (> 1 0.5+0.1i))
(err/rt-test (< 1 'a))
(err/rt-test (< 1 2 'a))
(err/rt-test (< 1 0 'a))
(err/rt-test (< 'a 1))
(err/rt-test (< 0.5+0.1i 1))
(err/rt-test (< 1 0.5+0.1i))
(err/rt-test (>= 1 'a))
(err/rt-test (>= 1 1 'a))
(err/rt-test (>= 1 2 'a))
(err/rt-test (>= 'a 1))
(err/rt-test (>= 0.5+0.1i 1))
(err/rt-test (>= 1 0.5+0.1i))
(err/rt-test (<= 1 'a))
(err/rt-test (<= 1 1 'a))
(err/rt-test (<= 1 0 'a))
(err/rt-test (<= 'a 1))
(err/rt-test (<= 0.5+0.1i 1))
(err/rt-test (<= 1 0.5+0.1i))

(arity-test = 2 -1)
(arity-test < 2 -1)
(arity-test > 2 -1)
(arity-test <= 2 -1)
(arity-test >= 2 -1)

(test #t zero? 0)
(test #t zero? 0.0)
(test #t zero? +0.0i)
(test #t zero? -0.0i)
(test #t zero? 0.0+0.0i)
(test #f zero? 1.0+0.0i)
(test #f zero? 1.0+1.0i)
(test #f zero? 0.0+1.0i)
(test #t zero? 0/1)
(test #f zero? 1)
(test #f zero? -1)
(test #f zero? -100)
(test #f zero? 1.0)
(test #f zero? -1.0)
(test #f zero? 1/2)
(test #f zero? -1/2)
(test #f zero? -1/2+2i)
(test #f zero? +inf.0)
(test #f zero? -inf.0)
(test #f zero? +nan.0)
(test #f zero? (expt 2 37))
(test #f zero? (expt -2 37))
(test #t positive? 4)
(test #f positive? -4)
(test #f positive? 0)
(test #t positive? 4.0)
(test #f positive? -4.0)
(test #f positive? 0.0)
(test #t positive? 2/4)
(test #f positive? -2/4)
(test #f positive? 0/2)
(test #t positive? +inf.0)
(test #f positive? -inf.0)
(test #f positive? +nan.0)
(test #t positive? (expt 2 37))
(test #f positive? (expt -2 37))
(test #f negative? 4)
(test #t negative? -4)
(test #f negative? 0)
(test #f negative? 4.0)
(test #t negative? -4.0)
(test #f negative? 0.0)
(test #f negative? 2/4)
(test #t negative? -2/4)
(test #f negative? 0/4)
(test #f negative? (expt 2 37))
(test #t negative? (expt -2 37))
(test #f negative? +inf.0)
(test #t negative? -inf.0)
(test #f negative? +nan.0)
(err/rt-test (negative? 5+0.0i))
(err/rt-test (negative? -5+0.0i))
(test #t odd? 3)
(test #f odd? 2)
(test #f odd? -4)
(test #t odd? -1)
(err/rt-test (odd? +inf.0))
(err/rt-test (odd? -inf.0))
(err/rt-test (odd? 5+0.0i))
(err/rt-test (odd? 4+0.0i))
(test #f odd? (expt 2 37))
(test #f odd? (expt -2 37))
(test #t odd? (add1 (expt 2 37)))
(test #t odd? (sub1 (expt -2 37)))
(test #f even? 3)
(test #t even? 2)
(test #t even? -4)
(test #f even? -1)
(err/rt-test (even? +inf.0))
(err/rt-test (even? -inf.0))
(err/rt-test (even? 4+0.0i))
(err/rt-test (even? 5+0.0i))
(test #t even? (expt 2 37))
(test #t even? (expt -2 37))
(test #f even? (add1 (expt 2 37)))
(test #f even? (sub1 (expt -2 37)))

(arity-test zero? 1 1)
(arity-test positive? 1 1)
(arity-test negative? 1 1)
(arity-test odd? 1 1)
(arity-test even? 1 1)

(err/rt-test (positive? 5+0.0i))
(err/rt-test (positive? -5+0.0i))
(err/rt-test (positive? 2+i))
(err/rt-test (negative? 2+i))
(err/rt-test (odd? 4.1))
(err/rt-test (odd? 4.1+0.0i))
(err/rt-test (odd? 4+1i))
(err/rt-test (even? 4.1))
(err/rt-test (even? 4.1+0.0i))
(err/rt-test (even? 4+1i))
(err/rt-test (even? +nan.0))

(err/rt-test (positive? 'i))
(err/rt-test (negative? 'i))
(err/rt-test (odd? 'a))
(err/rt-test (even? 'a))
(err/rt-test (odd? 'i))
(err/rt-test (even? 'i))

(test 5 max 5)
(test 5 min 5)
(test 38 max 34 5 7 38 6)
(test -24 min 3  5 5 330 4 -24)
(test 38.0 max 34 5.0 7 38 6)
(test -24.0 min 3  5 5 330 4 -24.0)
(test 2/3 max 1/2 2/3)
(test 2/3 max 2/3 1/2)
(test 2/3 max 2/3 -4/5)
(test 1/2 min 1/2 2/3)
(test 1/2 min 2/3 1/2)
(test -4/5 min 2/3 -4/5)
(test +inf.0 max +inf.0 0 -inf.0)
(test -inf.0 min +inf.0 0 -inf.0)
(test-nan.0 max +inf.0 +nan.0 0 -inf.0)
(test-nan.0 min +inf.0 0 +nan.0 -inf.0)
(err/rt-test (min 9.0+0.0i 100))
(err/rt-test (min 9.0+0.0i 8))
(err/rt-test (min 100 9.0+0.0i))
(err/rt-test (min 8 9.0+0.0i))
(err/rt-test (max 9.0+0.0i 100))
(err/rt-test (max 9.0+0.0i 8))
(err/rt-test (max 100 9.0+0.0i))
(err/rt-test (max 8 9.0+0.0i))

(test (expt 5 27) max 9 (expt 5 27))
(test (expt 5 29) max (expt 5 29) (expt 5 27))
(test (expt 5 29) max (expt 5 27) (expt 5 29))
(test (expt 5 27) max (expt 5 27) 9)
(test (expt 5 27) max (expt 5 27) (- (expt 5 29)))
(test (expt 5 27) max (- (expt 5 29)) (expt 5 27))
(test (- (expt 5 27)) max (- (expt 5 27)) (- (expt 5 29)))
(test (- (expt 5 27)) max (- (expt 5 29)) (- (expt 5 27)))
(test 9 min 9 (expt 5 27))
(test (expt 5 27) min (expt 5 29) (expt 5 27))
(test (expt 5 27) min (expt 5 27) (expt 5 29))
(test 9 min (expt 5 27) 9)
(test (- (expt 5 29)) min (expt 5 27) (- (expt 5 29)))
(test (- (expt 5 29)) min (- (expt 5 29)) (expt 5 27))
(test (- (expt 5 29)) min (- (expt 5 27)) (- (expt 5 29)))
(test (- (expt 5 29)) min (- (expt 5 29)) (- (expt 5 27)))

(err/rt-test (max 0 'a))
(err/rt-test (min 0 'a))
(err/rt-test (max 'a 0))
(err/rt-test (min 'a 0))
(err/rt-test (max 'a))
(err/rt-test (min 'a))
(err/rt-test (min 2 4+i))
(err/rt-test (max 2 4+i))
(err/rt-test (min 4+i))
(err/rt-test (max 4+i))

(arity-test max 1 -1)
(arity-test min 1 -1)

(test 0 +)
(test 7 + 3 4)
(test 6 + 1 2 3)
(test 7.0 + 3 4.0)
(test 6.0 + 1 2.0 3)
(test 19/12 + 1/4 1/3 1)
(test +i + +i)
(test 3/2+1i + 1 2+2i -i -3/2)
(test 3 + 3)
(test 0 +)
(test 4 * 4)
(test 16.0 * 4 4.0)
(test 1 *)
(test 6/25 * 3/5 1/5 2)
(test #i+6/25 * 3/5 1/5 2.0)
(test +6/25i * 3/5 1/5 2 +i)
(test (make-rectangular 0 #i+6/25) * 3/5 1/5 2.0 +i)
(test 18805208620685182736256260714897 
      * (sub1 (expt 2 31))  
      8756857658476587568751)
(test 1073741874 + (- (expt 2 30) 50) 100) ; fixnum -> bignum for 32 bits
(test -1073741874 - (- 50 (expt 2 30)) 100) ; fixnum -> bignum for 32 bits
(test 10.0+0.0i + 9.0+0.0i 1)
(test 10.0+0.0i + 9.0+0.0i 1-0.0i)
(test 9.0+0.0i * 9.0+0.0i 1)
(test 10.0-1.0i + 9.0+0.0i 1-1.0i)
(test 0 * 0 10.0)
(test 0 * 0 +inf.0)
(test 0 * 0 +nan.0)
(test 0 / 0 0.0)
(test 0 / 0 +inf.0)
(test 0 / 0 -inf.0)
(test 0 / 0 +nan.0)
(test -0.0 + 0 -0.0)
(test -0.0 + -0.0 0)
(test -0.0 - -0.0 0)

(test -0.0 - 0.0)
(test 0.0 - -0.0)
(test -0.0 - 0 0.0)
(test 0.0 - 0 -0.0)

(arity-test * 0 -1)
(arity-test + 0 -1)
(arity-test - 1 -1)
(arity-test / 1 -1)

(test 2 add1 1)
(test 0 add1 -1)
(test 2.0 add1 1.0)
(test 0.0 add1 -1.0)
(test 3/2 add1 1/2)
(test 1/2 add1 -1/2)
(test 2.0+i add1 1.0+i)
(test 0.0+i add1 -1.0+i)
(test 0.0+0.0i add1 -1+0.0i)
(test 0.0-0.0i add1 -1-0.0i)
(test 1073741824 add1 #x3FFFFFFF) ; fixnum boundary case

(err/rt-test (add1 "a"))
(arity-test add1 1 1)

(test 1 sub1 2)
(test -2 sub1 -1)
(test 1.0 sub1 2.0)
(test -2.0 sub1 -1.0)
(test -1/2 sub1 1/2)
(test -3/2 sub1 -1/2)
(test 1.0+i sub1 2.0+i)
(test -2.0+i sub1 -1.0+i)
(test -2.0+0.0i sub1 -1+0.0i)
(test -2.0-0.0i sub1 -1-0.0i)
(test -1073741824 sub1 -1073741823) ; fixnum boundary case

(err/rt-test (sub1 "a"))
(arity-test sub1 1 1)

(test 1024 expt 2 10)
(test 1/1024 expt 2 -10)
(test 1/1024 expt 1/2 10)
(test (/ 1 (expt 2 10000)) expt 1/2 10000)
(test 2 expt 4 1/2)
(test 2.0 expt 4 0.5)
(test (sqrt 5) expt 5 1/2)
(test 18446744073709551616 expt (expt 2 32) 2)
(arity-test expt 2 2)

(test 31525197391593472 inexact->exact 31525197391593473.0)
(test 31525197391593476 inexact->exact 31525197391593476.0)
(test 31525197391593476 inexact->exact 31525197391593476.0)

(test 0 apply + (map inexact->exact (list 3.2d+270 -2.4d+270 -8d+269)))
(test 0 apply + (map inexact->exact (list 3.2f+7 -2.4f+7 -8f+6)))

(test #t positive? (inexact->exact 0.1))
(test #t negative? (inexact->exact -0.1))
(test 0 + (inexact->exact -0.1) (inexact->exact 0.1))
(arity-test inexact->exact 1 1)
(err/rt-test (inexact->exact 'a))
(test 1+i inexact->exact 1.0+1.0i)
(test 1 inexact->exact 1.0+0.0i)
(test 1 inexact->exact 1.0-0.0i)

(test #t positive? (exact->inexact 1/10))
(test #t negative? (exact->inexact -1/10))
(test 0.0 + (exact->inexact -1/10) (exact->inexact 1/10))
(arity-test exact->inexact 1 1)
(err/rt-test (exact->inexact 'a))
(test 1.0+1.0i exact->inexact 1+1i)
(test 1.0+0.0i exact->inexact 1+0.0i)
(test (expt 7 30) inexact->exact (expt 7 30))

(err/rt-test (inexact->exact +inf.0))
(err/rt-test (inexact->exact -inf.0))
(err/rt-test (inexact->exact +nan.0))

(err/rt-test (* 'a 0))
(err/rt-test (+ 'a 0))
(err/rt-test (/ 'a 0))
(err/rt-test (- 'a 0))
(err/rt-test (+ 0 'a))
(err/rt-test (* 0 'a))
(err/rt-test (- 0 'a))
(err/rt-test (/ 0 'a))
(err/rt-test (+ 'a))
(err/rt-test (* 'a))
(err/rt-test (- 'a))
(err/rt-test (/ 'a))

(define (test-inf-plus-times v)
  (define (test+ +)
    (test +inf.0 + v (+ +inf.0))
    (test -inf.0 + v (+ -inf.0))
    (test +inf.0 + (- v) (+ +inf.0))
    (test -inf.0 + (- v) (+ -inf.0))
    
    (test +inf.0 + +inf.0 v)
    (test -inf.0 + -inf.0 v)
    (test +inf.0 + +inf.0 (- v))
    (test -inf.0 + -inf.0 (- v))

    (test-nan.0 + +nan.0 v)
    (test-nan.0 + v +nan.0))

  (test+ +)
  (test+ -)
  
  (test +inf.0 * +inf.0 v)
  (test -inf.0 * -inf.0 v)
  (test -inf.0 * +inf.0 (- v))
  (test +inf.0 * -inf.0 (- v))

  (test +inf.0 * v +inf.0)
  (test -inf.0 * v -inf.0)
  (test -inf.0 * (- v) +inf.0)
  (test +inf.0 * (- v) -inf.0)

  (test-nan.0 * +nan.0 v)
  (test-nan.0 * v +nan.0))

(test-inf-plus-times 1)
(test-inf-plus-times 1.0)
(test-inf-plus-times (expt 2 100))

(test -inf.0 - +inf.0)
(test +inf.0 - -inf.0)
(test +inf.0 + +inf.0 +inf.0)
(test -inf.0 + -inf.0 -inf.0)
(test-nan.0 + +inf.0 -inf.0)
(test-nan.0 - +inf.0 +inf.0)
(test-nan.0 - -inf.0 -inf.0)
(test +inf.0 * +inf.0 +inf.0)
(test -inf.0 * +inf.0 -inf.0)
(test 0 * +inf.0 0)
(test-nan.0 * +inf.0 0.0)
(test-nan.0 + +nan.0 +nan.0)
(test-nan.0 - +nan.0 +nan.0)
(test-nan.0 * +nan.0 +nan.0)

(test 1/2 / 1 2)
(test -1/3 / -1 3)
(test -1/3 / 1 -3)
(test 1/2 / 1/4 1/2)
(test 0.5 / 1 2.0)
(test 0.5 / 1.0 2)
(test 1/2+3/2i / 1+3i 2)
(test 1/5-3/5i / 2 1+3i)
(test 0.5+0.0i / 1+0.0i 2)
(test 0.25-0.0i / 1 4+0.0i)
(test 0.25+0.0i / 1+0.0i 4+0.0i)
(test 0 / 0 4+3i)
(test 0.25+0.0i / 1e300+1e300i (* 4 1e300+1e300i))
(test 0.25+0.0i / 1e-300+1e-300i (* 4 1e-300+1e-300i))
(test 1/2-1/2i / 1+1i)
(test 1/2+1/2i / 1-1i)
(test 1/5-2/5i / 1+2i)
(test 1/5+2/5i / 1-2i)
(test 2/5-1/5i / 2+1i)
(test 2/5+1/5i / 2-1i)
(test 0.5-0.5i / 1.0+1.0i)
(test 0.5+0.5i / 1.0-1.0i)
(test 0.2-0.4i / 1.0+2.0i)
(test 0.2+0.4i / 1.0-2.0i)
(test 0.4-0.2i / 2.0+1.0i)
(test 0.4+0.2i / 2.0-1.0i)

(test 3 / 1 1/3)
(test -3 / 1 -1/3)
(test -3 / -1 1/3)
(test 3 / -1 -1/3)
(test 1/3 / 1 3)
(test -1/3 / 1 -3)
(test -1/3 / -1 3)
(test 1/3 / -1 -3)
(test 3/2 / 1 2/3)
(test -3/2 / 1 -2/3)
(test -3/2 / -1 2/3)
(test 3/2 / -1 -2/3)

(test (expt 3 50) / 1 (/ 1 (expt 3 50)))
(test (- (expt 3 50)) / 1 (- (/ 1 (expt 3 50))))
(test (- (expt 3 50)) / -1 (/ 1 (expt 3 50)))
(test (expt 3 50) / -1 (- (/ 1 (expt 3 50))))
(test (/ 1 (expt 3 50)) / 1 (expt 3 50))
(test (- (/ 1 (expt 3 50))) / 1 (- (expt 3 50)))
(test (- (/ 1 (expt 3 50))) / -1 (expt 3 50))
(test (/ 1 (expt 3 50)) / -1 (- (expt 3 50)))
(test (/ (expt 3 50) (expt 2 70)) / 1 (/ (expt 2 70) (expt 3 50)))
(test (- (/ (expt 3 50) (expt 2 70))) / 1 (- (/ (expt 2 70) (expt 3 50))))
(test (- (/ (expt 3 50) (expt 2 70))) / -1 (/ (expt 2 70) (expt 3 50)))
(test (/ (expt 3 50) (expt 2 70)) / -1 (/ (- (expt 2 70)) (expt 3 50)))

(test (- (expt 2 30)) / (- (expt 2 30)) 1)
(test (expt 2 30) / (- (expt 2 30)) -1)
(test (expt 2 29) / (- (expt 2 30)) -2)
(test -1/1073741824 / (- (expt 2 30)))

(test +inf.0 / 1.0 0.0)
(test -inf.0 / -1.0 0.0)
(test +inf.0 / -1.0 -0.0)
(test -inf.0 / 1.0 -0.0)

(define (make-test-inf-zero-div zero -zero inf -inf)
  (lambda (v)
    (test zero / v +inf.0)
    (test -zero / v -inf.0)
    (test -zero / (- v) +inf.0)
    (test zero / (- v) -inf.0)
    
    (test inf / +inf.0 v)
    (test -inf / -inf.0 v)
    (test -inf / +inf.0 (- v))
    (test inf / -inf.0 (- v))
    
    (unless (zero? v)
      (test zero / 0.0 v)
      (test -zero / 0.0 (- v))
      (test -zero / -0.0 v)
      (test zero / -0.0 (- v))
      
      (test inf / v 0.0)
      (test -inf / (- v) 0.0)
      (test -inf / v -0.0)
      (test inf / (- v) -0.0))
    
    (test-nan.0 / +nan.0 v)
    (test-nan.0 / v +nan.0)))

(define test-inf-zero-div (make-test-inf-zero-div 0.0 -0.0 +inf.0 -inf.0))
(define test-neg-inf-zero-div (make-test-inf-zero-div -0.0 0.0 -inf.0 +inf.0))

(test-inf-zero-div big-num)
(test-inf-zero-div (/ big-num 3))
(test-inf-zero-div 0.0)

(test-neg-inf-zero-div (- big-num))
(test-neg-inf-zero-div (- (/ big-num 3)))
(test-neg-inf-zero-div -0.0)

(test-nan.0 / +inf.0 +inf.0)
(test-nan.0 / +inf.0 -inf.0)
(test-nan.0 / +nan.0 -nan.0)

(test 1.0 exact->inexact (/ big-num (add1 big-num)))

(test 0.0 values (exact->inexact (/ (expt 2 5000) (add1 (expt 2 5000000)))))
(test -0.0 values (exact->inexact (/ (- (expt 2 5000)) (add1 (expt 2 5000000)))))
(test #t positive? (exact->inexact (* 5 (expt 10 -324))))
(test #t negative? (exact->inexact (* -5 (expt 10 -324))))
(test #t zero? (exact->inexact (* 5 (expt 10 -325))))
(test #t positive? (exact->inexact (* 45 (expt 10 -325))))

(err/rt-test (/ 0) exn:fail:contract:divide-by-zero?)
(err/rt-test (/ 1 0) exn:fail:contract:divide-by-zero?)
(err/rt-test (/ 1/2 0) exn:fail:contract:divide-by-zero?)
(err/rt-test (/ 1+2i 0) exn:fail:contract:divide-by-zero?)
(err/rt-test (/ 1.0 0) exn:fail:contract:divide-by-zero?)

(test -1 - 3 4)
(test -3 - 3)
(test -1.0 - 3.0 4)
(test -3.0 - 3.0)
(test 7 abs -7)
(test (expt 7 100) abs (- (expt 7 100)))
(test (expt 7 100) abs (expt 7 100))
(test 7.0 abs -7.0)
(test 7 abs 7)
(test 0 abs 0)
(test 1/2 abs 1/2)
(test 1/2 abs -1/2)
(test +inf.0 abs +inf.0)
(test +inf.0 abs -inf.0)
(test-nan.0 abs -nan.0)
(err/rt-test (abs -4.0+0.0i))

(test 1073741823 abs -1073741823)
(test 1073741823 abs 1073741823)
(test 1073741824 abs -1073741824)
(test 1073741824 abs 1073741824)
(test 1073741825 abs -1073741825)
(test 1073741825 abs 1073741825)

(arity-test abs 1 1)
(err/rt-test (-) exn:application:arity?)
(err/rt-test (abs 'a))
(err/rt-test (abs +5i))

(test 5 quotient 35 7)
(test 5.0 quotient 35 7.0)
(test 5.0 quotient 36 7.0)
(test 5.0 quotient 36.0 7)
(test -5 quotient -35 7)
(test -5.0 quotient -35 7.0)
(test -5 quotient 35 -7)
(test -5.0 quotient 35 -7.0)
(test 5 quotient -35 -7)
(test 5.0 quotient -35 -7.0)
(test -5.0 quotient -36 7.0)
(test -5.0 quotient 36.0 -7)
(err/rt-test (quotient 36.0 -7+0.0i))
(err/rt-test (quotient 36.0+0.0i -7))
(test 0 quotient 0 5.0)
(test 0 quotient 0 -5.0)
(test (expt 2 30) quotient (- (expt 2 30)) -1)
(test 1 modulo 13 4)
(test 1 remainder 13 4)
(test 1.0 modulo 13 4.0)
(test 1.0 remainder 13 4.0)
(test 3 modulo -13 4)
(test -1 remainder -13 4)
(test 3.0 modulo -13 4.0)
(test -1.0 remainder -13 4.0)
(test -3 modulo 13 -4)
(test 1 remainder 13 -4)
(test -3.0 modulo 13.0 -4)
(test 1.0 remainder 13.0 -4)
(test -1 modulo -13 -4)
(test -1 remainder -13 -4)
(test -1.0 modulo -13 -4.0)
(test -1.0 remainder -13 -4.0)
(err/rt-test (modulo -13 -4.0+0.0i))
(err/rt-test (remainder -13 -4.0+0.0i))
(err/rt-test (modulo -13+0.0i -4.0))
(err/rt-test (remainder -13+0.0i -4.0))
(test -2 remainder -3333333332 -3)
(test -2 modulo -3333333332 -3)
(test 2 remainder 3333333332 -3)
(test -1 modulo 3333333332 -3)
(test 0 modulo 4 2)
(test 0 modulo -4 2)
(test 0 modulo 4 -2)
(test 0 modulo -4 -2)
(test 0.0 modulo 4.0 2)
(test 0.0 modulo -4.0 2)
(test 0.0 modulo 4.0 -2)
(test 0.0 modulo -4.0 -2)
(test 0 remainder 4 2)
(test 0 remainder -4 2)
(test 0 remainder 4 -2)
(test 0 remainder -4 -2)
(test 0.0 remainder 4.0 2)
(test 0.0 remainder -4.0 2)
(test 0.0 remainder 4.0 -2)
(test 0.0 remainder -4.0 -2)
(test 0 modulo 0 5.0)
(test 0 modulo 0 -5.0)
(test 0 remainder 0 5.0)
(test 0 remainder 0 -5.0)
(test 0 modulo (- (expt 2 30)) -1)
(test 0 remainder (- (expt 2 30)) -1)
(define (divtest n1 n2)
	(= n1 (+ (* n2 (quotient n1 n2))
		 (remainder n1 n2))))
(test #t divtest 238 9)
(test #t divtest -238 9)
(test #t divtest 238 -9)
(test #t divtest -238 -9)

(test 13.0 quotient 1324.0 100)

(err/rt-test (quotient 6 0) exn:fail:contract:divide-by-zero?)
(err/rt-test (modulo 6 0) exn:fail:contract:divide-by-zero?)
(err/rt-test (remainder 6 0) exn:fail:contract:divide-by-zero?)
(err/rt-test (quotient 6 0.0) exn:fail:contract:divide-by-zero?)
(err/rt-test (modulo 6 0.0) exn:fail:contract:divide-by-zero?)
(err/rt-test (remainder 6 0.0) exn:fail:contract:divide-by-zero?)
(err/rt-test (quotient 6 -0.0) exn:fail:contract:divide-by-zero?)
(err/rt-test (modulo 6 -0.0) exn:fail:contract:divide-by-zero?)
(err/rt-test (remainder 6 -0.0) exn:fail:contract:divide-by-zero?)

(define (test-qrm-inf v)
  (define iv (exact->inexact v))

  (err/rt-test (quotient v +inf.0))
  (err/rt-test (quotient v -inf.0))
  (err/rt-test (remainder v +inf.0))
  (err/rt-test (remainder v -inf.0))
  (err/rt-test (modulo v +inf.0))
  (err/rt-test (modulo v -inf.0))

  (err/rt-test (quotient +inf.0 v))
  (err/rt-test (quotient -inf.0 v))
  (err/rt-test (remainder +inf.0 v))
  (err/rt-test (remainder -inf.0 v))
  (err/rt-test (modulo +inf.0 v))
  (err/rt-test (modulo -inf.0 v)))

(test-qrm-inf 9)
(test-qrm-inf 9.0)
(test-qrm-inf (expt 2 100))
(test-qrm-inf 0.0)
(test-qrm-inf -0.0)

;; Check 0.0 combinations
(test -0.0 quotient -0.0 2.0)
(test 0.0 quotient -0.0 -2.0)
(test 0.0 quotient 0.0 2.0)
(test -0.0 quotient 0.0 -2.0)
(test 0.0 modulo -0.0 2.0)
(test 0.0 modulo -0.0 -2.0)
(test 0.0 modulo 0.0 2.0)
(test 0.0 modulo 0.0 -2.0)
(test 0.0 remainder -0.0 2.0)
(test 0.0 remainder -0.0 -2.0)
(test 0.0 remainder 0.0 2.0)
(test 0.0 remainder 0.0 -2.0)

(arity-test quotient 2 2)
(arity-test modulo 2 2)
(arity-test remainder 2 2)

(err/rt-test (quotient 'a 1))
(err/rt-test (quotient 1 'a))
(err/rt-test (quotient 1 +nan.0))
(err/rt-test (quotient +nan.0 1))
(err/rt-test (modulo 'a 1))
(err/rt-test (modulo 1 'a))
(err/rt-test (modulo +nan.0 1))
(err/rt-test (modulo 1 +nan.0))
(err/rt-test (remainder 'a 1))
(err/rt-test (remainder 1 'a))
(err/rt-test (remainder +nan.0 1))
(err/rt-test (remainder 1 +nan.0))
(err/rt-test (quotient 'a 1.0))
(err/rt-test (quotient 1.0 'a))
(err/rt-test (modulo 'a 1.0))
(err/rt-test (modulo 1.0 'a))
(err/rt-test (remainder 'a 1.0))
(err/rt-test (remainder 1.0 'a))
(err/rt-test (quotient 1/2 1))
(err/rt-test (remainder 1/2 1))
(err/rt-test (modulo 1/2 1))
(err/rt-test (quotient 2 1/2))
(err/rt-test (remainder 2 1/2))
(err/rt-test (modulo 2 1/2))
(err/rt-test (quotient 12.3 1))
(err/rt-test (remainder 12.3 1))
(err/rt-test (modulo 12.3 1))
(err/rt-test (quotient 2 12.3))
(err/rt-test (remainder 2 12.3))
(err/rt-test (modulo 2 12.3))
(err/rt-test (quotient 1+2i 1))
(err/rt-test (remainder 1+2i 1))
(err/rt-test (modulo 1+2i 1))
(err/rt-test (quotient 2 1+2i))
(err/rt-test (remainder 2 1+2i))
(err/rt-test (modulo 2 1+2i))

#| dyoo: no support for bitwise operations yet.
(test 10 bitwise-ior 10)
(test 10 bitwise-and 10)
(test 10 bitwise-xor 10)
(test 7 bitwise-ior 3 4)
(test 0 bitwise-and 3 4)
(test 7 bitwise-xor 3 4)
(test 7 bitwise-ior 3 4 1)
(test 1 bitwise-and 3 5 1)
(test 6 bitwise-xor 3 4 1)

(test #x1ffff7777 bitwise-ior #x1aaaa5555 #x155553333)
(test #x100001111 bitwise-and #x1aaaa5555 #x155553333)
(test #x0ffff6666 bitwise-xor #x1aaaa5555 #x155553333)

(test #x3ffff7777 bitwise-ior #x2aaaa5555 #x155553333)
(test #x000001111 bitwise-and #x2aaaa5555 #x155553333)
(test #x3ffff6666 bitwise-xor #x2aaaa5555 #x155553333)

(test #x3ffff7777 bitwise-ior #x2aaaa5555 #x155553333)
(test #x000001111 bitwise-and #x2aaaa5555 #x155553333)
(test #x3ffff6666 bitwise-xor #x2aaaa5555 #x155553333)

(test #xfffffffffffffe bitwise-not #x-FFFFFFFFFFFFFF)
(test #x-100000000000000 bitwise-not #xFFFFFFFFFFFFFF)

(test (bitwise-and (bitwise-not #x-2aaaa5555) (bitwise-not #x-15555aaaa))
      bitwise-not (bitwise-ior #x-2aaaa5555 #x-15555aaaa))
(test (bitwise-and (bitwise-not #x-2aaaa5555) (bitwise-not #x-155553333))
      bitwise-not (bitwise-ior #x-2aaaa5555 #x-155553333))
(test (bitwise-and (bitwise-not #x-2aaaa5555) (bitwise-not #x-15555333))
      bitwise-not (bitwise-ior #x-2aaaa5555 #x-15555333))

(test #x-155553333 bitwise-xor #x-2aaaa5555 (bitwise-xor #x-2aaaa5555 #x-155553333))
(test #x-15555333 bitwise-xor #x-2aaaa5555 (bitwise-xor #x-2aaaa5555 #x-15555333))

(test -1 bitwise-and)
(test 0 bitwise-ior)
(test 0 bitwise-xor)

(arity-test bitwise-ior 0 -1)
(arity-test bitwise-and 0 -1)
(arity-test bitwise-xor 0 -1)
(arity-test bitwise-not 1 1)

(define error-test-bitwise-procs
  (lambda (v)
    (err/rt-test (bitwise-ior v))
    (err/rt-test (bitwise-and v))
    (err/rt-test (bitwise-xor v))
    (err/rt-test (bitwise-not v))
    (err/rt-test (bitwise-ior 1 v))
    (err/rt-test (bitwise-and 1 v))
    (err/rt-test (bitwise-xor 1 v))
    (err/rt-test (bitwise-ior v 1))
    (err/rt-test (bitwise-and v 1))
    (err/rt-test (bitwise-xor v 1))))

(error-test-bitwise-procs 1.0)
(error-test-bitwise-procs 1/2)
(error-test-bitwise-procs 1+2i)
(error-test-bitwise-procs 1.0+0.0i)
(error-test-bitwise-procs +inf.0)
(error-test-bitwise-procs ''a)

(test 1 arithmetic-shift 1 0)
(test 1024 arithmetic-shift 1 10)
(test 1 arithmetic-shift 1024 -10)
(test 256 arithmetic-shift 1024 -2)
(test 0 arithmetic-shift 1024 -11)
(test 0 arithmetic-shift 1024 -20)
(test 0 arithmetic-shift 1024 -40)
(test 0 arithmetic-shift 1024 -20000000000000000000)
(test 0 arithmetic-shift 0 100)
(test 0 arithmetic-shift 0 -100)
(test 0 arithmetic-shift 17 -32)

(test (expt 2 40) arithmetic-shift (expt 2 40) 0)
(test (expt 2 50) arithmetic-shift (expt 2 40) 10)
(test (expt 2 30) arithmetic-shift (expt 2 40) -10) ; somewhere close to here is a boundary...
(test (expt 2 29) arithmetic-shift (expt 2 40) -11)
(test (expt 2 31) arithmetic-shift (expt 2 40) -9)
(test 1 arithmetic-shift (expt 2 40) -40)
(test 0 arithmetic-shift (expt 2 40) -41)
(test 0 arithmetic-shift (expt 2 40) -100)

(test -1 arithmetic-shift -1 0)
(test -1024 arithmetic-shift -1 10)
(test -1 arithmetic-shift -1024 -10)
(test -256 arithmetic-shift -1024 -2)
(test -1 arithmetic-shift -1024 -11)
(test -1 arithmetic-shift -1024 -20)
(test -1 arithmetic-shift -1024 -20000000000000000000)

(test (- (expt 2 40)) arithmetic-shift (- (expt 2 40)) 0)
(test (- (expt 2 50)) arithmetic-shift (- (expt 2 40)) 10)
(test (- (expt 2 30)) arithmetic-shift (- (expt 2 40)) -10) ; somewhere close to here is a boundary...
(test (- (expt 2 29)) arithmetic-shift (- (expt 2 40)) -11)
(test (- (expt 2 31)) arithmetic-shift (- (expt 2 40)) -9)
(test -1 arithmetic-shift (- (expt 2 40)) -40)
(test -1 arithmetic-shift (- (expt 2 40)) -41)
(test -1 arithmetic-shift (- (expt 2 40)) -100)

(test 0 arithmetic-shift (sub1 (expt 2 30)) -32)
(test 0 arithmetic-shift (sub1 (expt 2 31)) -32)
(test 0 arithmetic-shift (sub1 (expt 2 32)) -32)
(test 1 arithmetic-shift (expt 2 32) -32)

(arity-test arithmetic-shift 2 2)
(err/rt-test (arithmetic-shift "a" 1))
(err/rt-test (arithmetic-shift 1 "a"))
(err/rt-test (arithmetic-shift 1.0 1))
(err/rt-test (arithmetic-shift 1 1.0))
(err/rt-test (arithmetic-shift 1 1.0+0.0i))
(err/rt-test (arithmetic-shift 1 (expt 2 80)) exn:fail:out-of-memory?)

(test #f bitwise-bit-set? 13 1)
(test #t bitwise-bit-set? 13 2)
(test #f bitwise-bit-set? 13 (expt 2 101))
(test #t bitwise-bit-set? -13 (expt 2 101))
(test #f bitwise-bit-set? (+ (expt 2 101) 13) 1)
(test #t bitwise-bit-set? (+ (expt 2 101) 13) 2)
(test #f bitwise-bit-set? (arithmetic-shift 13 101) (+ 101 1))
(test #t bitwise-bit-set? (arithmetic-shift 13 101) (+ 101 2))
(test #f bitwise-bit-set? (- (expt 2 101)) 0)
(test #f bitwise-bit-set? (- (expt 2 101)) 1)
(test #t bitwise-bit-set? (- (sub1 (expt 2 101))) 0)
(test #t bitwise-bit-set? (bitwise-not (expt 2 101)) 70)

(arity-test bitwise-bit-set? 2 2)
(err/rt-test (bitwise-bit-set? "a" 1))
(err/rt-test (bitwise-bit-set? 13 "a"))
(err/rt-test (bitwise-bit-set? 13 -1))
(err/rt-test (bitwise-bit-set? 13 (- (expt 2 101))))

(test 0 bitwise-bit-field 13 0 0)
(test 1 bitwise-bit-field 13 0 1)
(test 0 bitwise-bit-field 13 1 1)
(test 0 bitwise-bit-field 13 1 2)
(test 2 bitwise-bit-field 13 1 3)
(test 0 bitwise-bit-field 13 3 3)
(test 6 bitwise-bit-field 13 1 4)
(test 6 bitwise-bit-field 13 1 10)
(test 6 bitwise-bit-field 13 1 100)
(test 3 bitwise-bit-field 13 2 10)
(test 3 bitwise-bit-field 13 2 100)
(test 0 bitwise-bit-field (arithmetic-shift 13 101) 0 0)
(test 6 bitwise-bit-field (arithmetic-shift 13 101) (+ 1 101) (+ 4 101))
(test #t 'all-six
      ;; checks boundaries of bignums
      (for/and ([i (in-range 101 171)])
        (and (= 6 (bitwise-bit-field (arithmetic-shift 13 i) (+ 1 i) (+ 4 i)))
             (= 6 (bitwise-bit-field (arithmetic-shift 13 i) (+ 1 i) 400)))))
(test 1 bitwise-bit-field -13 0 1)
(test 0 bitwise-bit-field -14 0 1)
(test 1 bitwise-bit-field -13 1 2)
(test 1 bitwise-bit-field -13 28 29)
(test #b111111111111 bitwise-bit-field -13 28 40)
(test #b111111111111 bitwise-bit-field -13 1028 1040)
(test 0 bitwise-bit-field (- (expt 2 101)) 0 0)
(test 1 bitwise-bit-field (- (sub1 (expt 2 101))) 0 1)
(test 1 bitwise-bit-field (bitwise-not (expt 2 101)) 70 71)
(test 7144187 bitwise-bit-field (expt 3 75) 0 24)

(test 42 bitwise-bit-field 42 0 32)
(test (sub1 (expt 2 32)) bitwise-bit-field -1 32 64)

(arity-test bitwise-bit-field 3 3)
(err/rt-test (bitwise-bit-field "a" 1 2))
(err/rt-test (bitwise-bit-field 13 -1 2))
(err/rt-test (bitwise-bit-field 13 0 -1))
(err/rt-test (bitwise-bit-field 13 2 1))
(err/rt-test (bitwise-bit-field 13 (expt 2 101) (sub1 (expt 2 101))))
|#

(test 4 gcd 0 4)
(test 4 gcd -4 0)
(test 4 gcd 4)
(test 4 gcd -4)
(test 4 gcd 32 -36)
(test 2 gcd 6 10 14)
(test 0 gcd)
(test 5 gcd 5)
(test 5.0 gcd 5.0 10)
(test 5.0 gcd -5.0 10)
(test 5.0 gcd 5.0 -10)
(test 5.0 gcd 5.0)
(test 5.0 gcd -5.0)
(test 3 gcd 0 0 3 0)
(test 3.0 gcd 0.0 0 3 0)
(test 0 gcd 0 0 0)
(err/rt-test (gcd 5.0+0.0i 10))
(err/rt-test (gcd 5.0 10+0.0i))
(test (expt 3 37) gcd (expt 9 35) (expt 6 37))
(test (expt 3 37) gcd (- (expt 9 35)) (expt 6 37))
(test (expt 3 37) gcd (expt 9 35) (- (expt 6 37)))
(test (expt 3 75) gcd (expt 3 75))
(test (expt 3 75) gcd (- (expt 3 75)))
(test 201 gcd (* 67 (expt 3 20)) (* 67 3))
(test 201 gcd (* 67 3) (* 67 (expt 3 20)))
(test 6 gcd (* 3 (expt 2 100)) 66)
(test 6 gcd 66 (* 3 (expt 2 100)))
(test 201.0 gcd (* 67 (expt 3 20)) (* 67. 3))
(test 201.0 gcd (* 67. 3) (* 67 (expt 3 20)))
(test (expt 9 35) gcd (expt 9 35) 0)
(test (expt 9 35) gcd 0 (expt 9 35))
(test 288 lcm 32 -36)
(test 12 lcm 2 3 4)
(test 1 lcm)
(test 5 lcm 5)
(test 5 lcm -5)
(test 0 lcm 123 0)
(test 0 lcm 0 0)
(test 0.0 lcm 0 0.0)
(test 0.0 lcm 0.0 0)
(test 30.0 lcm 5 6.0)
(test 6.0 lcm 6.0)
(test 6.0 lcm -6.0)
(err/rt-test (lcm 5 6.0+0.0i))
(err/rt-test (lcm 5+0.0i 6.0))
(test 0.0 lcm 123 0.0)
(test 0.0 lcm 123 -0.0)
(test (* (expt 2 37) (expt 9 35)) lcm (expt 9 35) (expt 6 37))
(test (* (expt 2 37) (expt 9 35)) lcm (- (expt 9 35)) (expt 6 37))
(test (* (expt 2 37) (expt 9 35)) lcm (expt 9 35) (- (expt 6 37)))

(err/rt-test (gcd +nan.0))
(err/rt-test (gcd +inf.0))
(err/rt-test (gcd -inf.0))
(err/rt-test (gcd 'a))
(err/rt-test (gcd 'a 1))
(err/rt-test (gcd 1 'a))
(err/rt-test (lcm +nan.0))
(err/rt-test (lcm +inf.0))
(err/rt-test (lcm -inf.0))
(err/rt-test (lcm 'a))
(err/rt-test (lcm 'a 1))
(err/rt-test (lcm 1 'a))
(err/rt-test (gcd 1/2))
(err/rt-test (gcd 3 1/2))
(err/rt-test (gcd 1/2 3))
(err/rt-test (lcm 1/2))
(err/rt-test (lcm 3 1/2))
(err/rt-test (lcm 1/2 3))
(err/rt-test (gcd 1+2i))
(err/rt-test (lcm 1+2i))
(err/rt-test (gcd 1 1+2i))
(err/rt-test (lcm 1 1+2i))
(err/rt-test (gcd +nan.0 5.0))
(err/rt-test (gcd 5.0 +nan.0))
(err/rt-test (lcm +nan.0 5.0))
(err/rt-test (lcm 5.0 +nan.0))
(err/rt-test (gcd +inf.0 5.0))
(err/rt-test (gcd 5.0 +inf.0))
(err/rt-test (lcm +inf.0 5.0))
(err/rt-test (lcm 5.0 +inf.0))

(arity-test gcd 0 -1)
(arity-test lcm 0 -1)

(test 2 floor 5/2)
(test 3 ceiling 5/2)
(test 2 round 5/2)
(test 2 truncate 5/2)
(test -3 floor -5/2)
(test -2 ceiling -5/2)
(test -2 round -5/2)
(test -2 truncate -5/2)

(test 1 floor 4/3)
(test 2 ceiling 4/3)
(test 1 round 4/3)
(test 1 truncate 4/3)
(test -2 floor -4/3)
(test -1 ceiling -4/3)
(test -1 round -4/3)
(test -1 truncate -4/3)

(test 1 floor 5/3)
(test 2 ceiling 5/3)
(test 2 round 5/3)
(test 1 truncate 5/3)
(test -2 floor -5/3)
(test -1 ceiling -5/3)
(test -2 round -5/3)
(test -1 truncate -5/3)

(test 2 floor 11/4)
(test 3 ceiling 11/4)
(test 3 round 11/4)
(test 2 truncate 11/4)
(test -3 floor -11/4)
(test -2 ceiling -11/4)
(test -3 round -11/4)
(test -2 truncate -11/4)

(test 2 floor 9/4)
(test 3 ceiling 9/4)
(test 2 round 9/4)
(test 2 truncate 9/4)
(test -3 floor -9/4)
(test -2 ceiling -9/4)
(test -2 round -9/4)
(test -2 truncate -9/4)

(test 2.0 floor 2.4)
(test 3.0 ceiling 2.4)
(test 2.0 round 2.4)
(test 2.0 truncate 2.4)
(test -3.0 floor -2.4)
(test -2.0 ceiling -2.4)
(test -2.0 round -2.4)
(test -2.0 truncate -2.4)

(test 2.0 floor 2.6)
(test 3.0 ceiling 2.6)
(test 3.0 round 2.6)
(test 2.0 truncate 2.6)
(test -3.0 floor -2.6)
(test -2.0 ceiling -2.6)
(test -3.0 round -2.6)
(test -2.0 truncate -2.6)

(test 2.0 round 2.5)
(test -2.0 round -2.5)
(test 4.0 round 3.5)
(test -4.0 round -3.5)

(define (test-zero-ident f)
  (test 0.0 f 0.0)
  (test -0.0 f -0.0))
(test-zero-ident round)
(test-zero-ident floor)
(test-zero-ident ceiling)
(test-zero-ident truncate)

(err/rt-test (floor 2.6+0.0i))
(err/rt-test (ceiling 2.6+0.0i))
(err/rt-test (round 2.6+0.0i))
(err/rt-test (truncate 2.6+0.0i))
(test +inf.0 floor +inf.0)
(test +inf.0 ceiling +inf.0)
(test +inf.0 round +inf.0)
(test +inf.0 truncate +inf.0)
(test -inf.0 floor -inf.0)
(test -inf.0 ceiling -inf.0)
(test -inf.0 round -inf.0)
(test -inf.0 truncate -inf.0)
(test +nan.0 floor +nan.0)
(test +nan.0 ceiling +nan.0)
(test +nan.0 round +nan.0)
(test +nan.0 truncate +nan.0)

(define (test-fcrt-int v)
  (test v floor v)
  (test v ceiling v)
  (test v round v)
  (test v truncate v))

(test-fcrt-int 2)
(test-fcrt-int 2.0)
(test-fcrt-int (expt 2 100))

(arity-test round 1 1)
(arity-test floor 1 1)
(arity-test ceiling 1 1)
(arity-test truncate 1 1)

(err/rt-test (floor 2+i))
(err/rt-test (ceiling 2+i))
(err/rt-test (truncate 2+i))
(err/rt-test (round 2+i))

(err/rt-test (floor "a"))
(err/rt-test (ceiling "a"))
(err/rt-test (truncate "a"))
(err/rt-test (round "a"))

(test 5 numerator 5)
(test 5000000000000 numerator 5000000000000)
(test 5.0 numerator 5.0)
(err/rt-test (numerator 5.0+0.0i))
(test 1 denominator 5)
(test 1 denominator 5000000000000)
(test 1.0 denominator 5.0)
(err/rt-test (denominator 5.0+0.0i))
(test 2 numerator 2/3)
(test 3 denominator 2/3)
(test 1000.0 round (* 10000.0 (/ (numerator 0.1) (denominator 0.1))))

(err/rt-test (numerator +inf.0))
(err/rt-test (numerator -inf.0))
(err/rt-test (numerator +nan.0))
(err/rt-test (denominator +inf.0))
(err/rt-test (denominator -inf.0))
(err/rt-test (denominator +nan.0))

(err/rt-test (numerator 'a))
(err/rt-test (numerator 1+2i))
(err/rt-test (denominator 'a))
(err/rt-test (denominator 1+2i))

(arity-test numerator 1 1)
(arity-test denominator 1 1)

(define (test-on-reals f filter)
  (test (filter 5) f 5)
  (test (filter 5.0) f 5.0)
  (test (filter 1/5) f 1/5)
  (test (filter (expt 2 100)) f (expt 2 100)))

(test 1+2i make-rectangular 1 2)
(test 1.0+2.0i make-rectangular 1.0 2)
(err/rt-test (make-rectangular 1.0+0.0i 2))
(err/rt-test (make-rectangular 1.0 2+0.0i))
(test-nan.0 real-part (make-rectangular +nan.0 1))
(test 1.0 imag-part (make-rectangular +nan.0 1))
(test-nan.0 imag-part (make-rectangular 1 +nan.0))
(test 1.0 real-part (make-rectangular 1 +nan.0))
(test +inf.0 real-part (make-rectangular +inf.0 -inf.0))
(test -inf.0 imag-part (make-rectangular +inf.0 -inf.0))

(test (make-rectangular +inf.0 -inf.0) * 1. (make-rectangular +inf.0 -inf.0))
(test (make-rectangular +inf.0 +inf.0) * +1.0i (make-rectangular +inf.0 -inf.0))
(test (make-rectangular -inf.0 +inf.0) * -3. (make-rectangular +inf.0 -inf.0))
(test (make-rectangular +inf.0 -inf.0) * (make-rectangular +inf.0 -inf.0) 1.)
(test (make-rectangular +inf.0 +inf.0) * (make-rectangular +inf.0 -inf.0) +1.0i)
(test (make-rectangular -inf.0 +inf.0) * (make-rectangular +inf.0 -inf.0) -3.)
(test (make-rectangular +inf.0 -inf.0) / (make-rectangular +inf.0 -inf.0) 1.)
(test (make-rectangular -inf.0 -inf.0) / (make-rectangular +inf.0 -inf.0) +1.0i)
(test (make-rectangular -inf.0 +inf.0) / (make-rectangular +inf.0 -inf.0) -3.)

;; Test division with exact zeros in demoniator where
;;  the exact zero gets polluted to an inexact zero unless
;;  it's special-cased
(test 0-0.0i / 0+1.0i -inf.0)
(test -0.0-0.0i / 1.0+1.0i -inf.0)
(test -0.0 / 0+1.0i 0-inf.0i)
(test -0.0+0.0i / 1.0+1.0i 0-inf.0i)

(test-i-nan.0 * 1.+0.i (make-rectangular +inf.0 -inf.0))
(test-i-nan.0 * 0.+1.0i (make-rectangular +inf.0 -inf.0))
(test-i-nan.0 * -3.+0.i (make-rectangular +inf.0 -inf.0))
(test-i-nan.0 * (make-rectangular +inf.0 -inf.0) 1.+0.i)
(test-i-nan.0 * (make-rectangular +inf.0 -inf.0) 0.+1.0i)
(test-i-nan.0 * (make-rectangular +inf.0 -inf.0) -3.+0.i)
(test-i-nan.0 / (make-rectangular +inf.0 -inf.0) 1.+0.i)
(test-i-nan.0 / (make-rectangular +inf.0 -inf.0) 0.+1.0i)
(test-i-nan.0 / (make-rectangular +inf.0 -inf.0) -3.+0.i)

(test 1 magnitude 1)
(test 1 magnitude -1)
(test 1.0 magnitude 1.0)
(test 1.0 magnitude -1.0)
(test big-num magnitude big-num)
(test big-num magnitude (- big-num))
(test 3/4 magnitude 3/4)
(test 3/4 magnitude -3/4)
(test 10.0 magnitude 10.0+0.0i)
(test 10.0 magnitude -10.0+0.0i)
(test 10.0 magnitude 0+10.0i)
(test 10 magnitude 0+10i)
(test 141421.0 round (* 1e-295 (magnitude 1e300+1e300i)))
(test 141421.0 round (* 1e+305 (magnitude 1e-300+1e-300i)))
(test +inf.0 magnitude +inf.0+inf.0i)
(test +inf.0 magnitude -inf.0-inf.0i)
(test +inf.0 magnitude 1+inf.0i)
(test +inf.0 magnitude +inf.0+1i)
(test +inf.0 magnitude +inf.0+0.0i)
(test +inf.0 magnitude 0.0+inf.0i)
(test +nan.0 magnitude +nan.0+inf.0i)
(test +nan.0 magnitude +inf.0+nan.0i)

(test 0 angle 1)
(test 0 angle 1.0)
(test 0 angle 0.0)
(test 0 angle big-num)
(test 0 angle 3/4)
(test 0.0 angle 3+0.0i)
(test-nan.0 angle +nan.0)
(let ([pi (atan 0 -1)])
  (test pi angle -1)
  (test pi angle -1.0)
  (test pi angle -0.0)
  (test pi angle (- big-num))
  (test pi angle -3/4)
  (test pi angle -3+0.0i))
(test -inf.0 atan 0+i)
(test -inf.0 atan 0-i)

(err/rt-test (angle 'a))
(err/rt-test (angle 0) exn:fail:contract:divide-by-zero?)
(err/rt-test (magnitude 'a))
(arity-test angle 1 1)
(arity-test magnitude 1 1)

(test 1 real-part 1+2i)
(test 1.0 real-part 1+2.0i)
(test 1.0 real-part 1+0.0i)
(test 1/5 real-part 1/5+2i)
(test-on-reals real-part (lambda (x) x))
(test 2.0 imag-part 1+2.0i)
(test 0.0 imag-part 1+0.0i)
(test -0.0 imag-part 1-0.0i)
(test 1/5 imag-part 1+1/5i)
(test-on-reals imag-part (lambda (x) 0))
(test-nan.0 real-part +nan.0)
(test 0 imag-part +nan.0)
(test 6@1 (lambda (x) x) 6.0@1.0)
(test 324.0 floor (* 100 (real-part 6@1)))
(test 50488.0 floor (* 10000 (imag-part 6@1)))
(test 1 make-polar 1 0)
(test 1.0+0.0i make-polar 1 0.0)
(test 1.0 make-polar 1.0 0)
(test 1.0+0.0i make-polar 1.0 0.0)
(err/rt-test (make-polar 1.0 0.0+0.0i))
(err/rt-test (make-polar 1.0+0.0i 0.0))
(let ([v (make-polar 1 1)])
  (test 5403.0 floor (* 10000 (real-part v)))
  (test 84147.0 floor (* 100000 (imag-part v)))
  (test 10000.0 round (* 10000.0 (magnitude v))))
(let ([v (make-polar 1 2)])
  (test -416.0 ceiling (* 1000 (real-part v)))
  (test 909.0 floor (* 1000 (imag-part v)))
  (test 1.0 magnitude v)
  (test 2.0 angle v))
(test-nan.0 make-polar +nan.0 0)
(test-i-nan.0 make-polar +nan.0 1)
(test-i-nan.0 make-polar 1 +nan.0)
(test-i-nan.0 make-polar 1 +inf.0)
(test-i-nan.0 make-polar 1 -inf.0)
(test +inf.0 make-polar +inf.0 0)
(test -inf.0 make-polar -inf.0 0)
(test (make-rectangular +inf.0 +inf.0) make-polar +inf.0 (atan 1 1))
(test (make-rectangular -inf.0 +inf.0) make-polar +inf.0 (atan 1 -1))
(test (make-rectangular +inf.0 -inf.0) make-polar +inf.0 (atan -1 1))
(test 785.0 floor (* 1000 (angle (make-rectangular 1 1))))
(test 14142.0 floor (* 10000 (magnitude (make-rectangular 1 1))))

(err/rt-test (make-rectangular 1 'a))
(err/rt-test (make-rectangular 'a 1))
(err/rt-test (make-rectangular 1+2i 1))
(err/rt-test (make-rectangular 1 1+2i))
(arity-test make-rectangular 2 2)

(err/rt-test (make-polar 1 'a))
(err/rt-test (make-polar 'a 1))
(err/rt-test (make-polar 1+2i 1))
(err/rt-test (make-polar 1 1+2i))
(arity-test make-polar 2 2)

(err/rt-test (real-part 'a))
(err/rt-test (imag-part 'a))
(arity-test real-part 1 1)
(arity-test imag-part 1 1)

(define (z-round c) (make-rectangular (round (real-part c)) (round (imag-part c))))

(test -1 * +i +i)
(test 1 * +i -i)
(test 2 * 1+i 1-i)
(test +2i * 1+i 1+i)
(test -3+4i - 3-4i)
(test 0.5+0.0i - (+ 0.5 +i) +i)
(test 1/2 - (+ 1/2 +i) +i)
(test 1.0+0.0i - (+ 1 +0.5i) +1/2i)

(test 1 sqrt 1)
(test 1.0 sqrt 1.0)
(test 25 sqrt 625)
(test 3/7 sqrt 9/49)
(test 0.5 sqrt 0.25)
(test +1i sqrt -1)
(test +2/3i sqrt -4/9)
(test +1.0i sqrt -1.0)
(test 1+1i sqrt +2i)
(test 2+1i sqrt 3+4i)
(test 2.0+0.0i sqrt 4+0.0i)
(test +inf.0 sqrt +inf.0)
(test (make-rectangular 0 +inf.0) sqrt -inf.0)
(test-nan.0 sqrt +nan.0)

;; Complex `sqrt' cases where both z and (magnitude z) are exact:
(test 1414.0 round (* 1000 (real-part (sqrt +4i))))
(test +1414.0 round (* 1000 (imag-part (sqrt +4i))))
(test 1414.0 round (* 1000 (real-part (sqrt -4i))))
(test -1414.0 round (* 1000 (imag-part (sqrt -4i))))
(test 1155.0 round (* 1000 (real-part (sqrt 1+4/3i))))
(test +577.0 round (* 1000 (imag-part (sqrt 1+4/3i))))
(test 1155.0 round (* 1000 (real-part (sqrt 1-4/3i))))
(test -577.0 round (* 1000 (imag-part (sqrt 1-4/3i))))

(test (expt 5 13) sqrt (expt 5 26))
(test 545915034.0 round (sqrt (expt 5 25)))
(test (make-rectangular 0 (expt 5 13)) sqrt (- (expt 5 26)))
(test (make-rectangular 0 545915034.0) z-round (sqrt (- (expt 5 25))))

(err/rt-test (sqrt "a"))
(arity-test sqrt 1 1)

(test 3 integer-sqrt 10)
(test 420 integer-sqrt (expt 3 11))
(test 97184015999 integer-sqrt (expt 2 73))
(test 0+3i integer-sqrt -10)
(test 0+420i integer-sqrt (expt -3 11))
(test 0+97184015999i integer-sqrt (expt -2 73))

(test 2.0 integer-sqrt 5.0)
(test 0+2.0i integer-sqrt -5.0)
(err/rt-test (integer-sqrt 5.0+0.0i))
(err/rt-test (integer-sqrt -5.0+0.0i))

(err/rt-test (integer-sqrt "a"))
(err/rt-test (integer-sqrt 1.1))
(err/rt-test (integer-sqrt 1+1i))
(arity-test integer-sqrt 1 1)

#| dyoo: no support for integer-sqrt/remainder
(test '(3 1) call-with-values (lambda () (integer-sqrt/remainder 10)) list)
(test '(420 747) call-with-values (lambda () (integer-sqrt/remainder (expt 3 11))) list)
(test '(97184015999 45402459391) call-with-values (lambda () (integer-sqrt/remainder (expt 2 73))) list)
(test '(0+3i -1) call-with-values (lambda () (integer-sqrt/remainder -10)) list)
(test '(0+420i -747) call-with-values (lambda () (integer-sqrt/remainder (expt -3 11))) list)
(test '(0+97184015999i -45402459391) call-with-values (lambda () (integer-sqrt/remainder (expt -2 73))) list)

(test '(2.0 1.0) call-with-values (lambda () (integer-sqrt/remainder 5.0)) list)
(test '(0+2.0i -1.0) call-with-values (lambda () (integer-sqrt/remainder -5.0)) list)
(err/rt-test (integer-sqrt/remainder 5.0+0.0i))
(err/rt-test (integer-sqrt/remainder -5.0+0.0i))

(err/rt-test (integer-sqrt/remainder "a"))
(err/rt-test (integer-sqrt/remainder 1.1))
(err/rt-test (integer-sqrt/remainder 1+1i))
(arity-test integer-sqrt/remainder 1 1)
|#


(test -13/64-21/16i expt -3/4+7/8i 2)
(let ([v (expt -3/4+7/8i 2+3i)])
  (test 3826.0 floor (* 10000000 (real-part v)))
  (test -137.0 ceiling (* 100000 (imag-part v))))
(test 49.0+0.0i expt 7 2+0.0i)
(test 49.0 floor (* 10 (expt 2 2.3)))
(test 189.0 floor (* 1000 (expt 2.3 -2)))
(test 1/4 expt 2 -2)
(test 1/1125899906842624 expt 2 -50)
(test 1/1024 expt 1/2 10)
(test 1024 expt 1/2 -10)
(test 707.0 floor (* 1000 (expt 1/2 1/2)))
(test 707.0 floor (* 1000 (expt 1/2 0.5)))
(test 707.0 floor (* 1000 (expt 0.5 1/2)))
(test 100.0+173.0i z-round (* 100 (expt -8 1/3)))
(test 100.0+173.0i z-round (* 100 (expt -8.0 1/3)))
(test 101.0+171.0i z-round (* 100 (expt -8 0.33)))
(test 101.0+171.0i z-round (* 100 (expt -8.0 0.33)))
(test 108.0+29.0i z-round (* 100 (expt 1+i 1/3)))
(test 25.0-43.0i z-round (* 100 (expt -8 -1/3)))

;; This choice doesn't make sense to me, but it fits
;;   with other standards and implementations:
(define INF-POWER-OF_NEGATIVE +inf.0)

(test +inf.0 expt 2 +inf.0)
(test +inf.0 expt +inf.0 10)
(test 0.0 expt +inf.0 -2)
(test 1 expt +inf.0 0)
(test 1.0 expt +inf.0 0.)
(test +inf.0 expt +inf.0 +inf.0)
(test INF-POWER-OF_NEGATIVE expt -2 +inf.0)
(test INF-POWER-OF_NEGATIVE expt -inf.0 +inf.0)
(test 0.0 expt 2 -inf.0)
(test -inf.0 expt -inf.0 11)
(test +inf.0 expt -inf.0 10)
(test 0.0 expt -inf.0 -2)
(test -0.0 expt -inf.0 -3)
(test 1 expt -inf.0 0)
(test 1.0 expt -inf.0 0.0)
(test 0.0 expt +inf.0 -inf.0)
(test 0.0 expt -2 -inf.0)
(test 0.0 expt -inf.0 -inf.0)
(test 1 expt +nan.0 0)
(test 0 expt 0 10)
(test 0 expt 0 10.0)
(test 0 expt 0 +inf.0)
(test-nan.0 expt 0 +nan.0)
(test 1 expt 1 +inf.0)
(test 1 expt 1 -inf.0)
(test 1 expt 1 -nan.0)
(test 0.0 expt 0.0 10)
(test 0.0 expt 0.0 +inf.0)
(test +inf.0 expt 0.0 -5)
(test -inf.0 expt -0.0 -5)
(test +inf.0 expt 0.0 -4)
(test +inf.0 expt -0.0 -4)
(test +inf.0 expt 0.0 -4.3)
(test +inf.0 expt -0.0 -4.3)
(test +inf.0 expt 0.0 -inf.0)
(test-nan.0 expt 0.0 +nan.0)
(test 1 expt 0 0)
(test 1.0 expt 0 0.0) ; to match (expt 0 0)
(test 1.0 expt 0 -0.0)
(test 1.0 expt 0.0 0.0)
(test 1.0 expt 0.0 0.0)
(test 1 expt 0.0 0)
(test 1 expt -0.0 0)
(test -0.0 expt -0.0 1)
(test-nan.0 expt +nan.0 10)
(test-nan.0 expt 2 +nan.0)

(test 0 expt 0 1+i)
(test 0 expt 0 1-i)

(test-nan.0 expt 1.0 +inf.0)
(test-nan.0 expt 1.0 -inf.0)
(test-nan.0 expt 1.0 +nan.0)

(test 0.0 expt 0.0 5)
(test -0.0 expt -0.0 5)
(test 0.0 expt 0.0 4)
(test 0.0 expt -0.0 4)
(test 0.0 expt 0.0 4.3)
(test 0.0 expt -0.0 4.3)

(test 0.0 expt 0.5 +inf.0)
(test +inf.0 expt 0.5 -inf.0)
(test INF-POWER-OF_NEGATIVE expt -0.5 -inf.0)
(test +inf.0 expt 1.5 +inf.0)
(test 0.0 expt 1.5 -inf.0)
(test 0.0 expt -0.5 +inf.0)
(test +inf.0 expt -0.5 -inf.0)
(test INF-POWER-OF_NEGATIVE expt -1.5 +inf.0)
(test 0.0 expt -1.5 -inf.0)

(err/rt-test (expt 0 -1) exn:fail:contract:divide-by-zero?)
(err/rt-test (expt 0 -1.0) exn:fail:contract:divide-by-zero?)
(err/rt-test (expt 0 -inf.0) exn:fail:contract:divide-by-zero?)
(err/rt-test (expt 0 -1+2i) exn:fail:contract:divide-by-zero?)
(err/rt-test (expt 0 -1.0+2i) exn:fail:contract:divide-by-zero?)
(err/rt-test (expt 0 0+2i) exn:fail:contract:divide-by-zero?)
(err/rt-test (expt 0 0.0+2i) exn:fail:contract:divide-by-zero?)
(err/rt-test (expt 0 -0.0+2i) exn:fail:contract:divide-by-zero?)
(err/rt-test (expt 0 0+0.0i) exn:fail:contract:divide-by-zero?)

(err/rt-test (expt 'a 0))
(err/rt-test (expt 'a 1))
(err/rt-test (expt 'a 3))
(err/rt-test (expt 0 'a))
(err/rt-test (expt 1 'a))
(err/rt-test (expt 3 'a))

;;;;From: fred@sce.carleton.ca (Fred J Kaudel)
;;; Modified by jaffer.
(define f3.9 (string->number "3.9"))
(define f4.0 (string->number "4.0"))
(define f-3.25 (string->number "-3.25"))
(define f.25 (string->number ".25"))
(define f4.5 (string->number "4.5"))
(define f3.5 (string->number "3.5"))
(define f0.0 (string->number "0.0"))
(define f0.8 (string->number "0.8"))
(define f1.0 (string->number "1.0"))
(newline)
(display ";testing inexact numbers; ")
(newline)
(test #t inexact? f3.9)
(test #f exact? f3.9)
(test #t 'inexact? (inexact? (max f3.9 4)))
(test f4.0 'max (max f3.9 4))
(test f4.0 'exact->inexact (exact->inexact 4))

; Should at least be close...
(test 4.0 round (log (exp 4.0)))
(test 125.0 round (* 1000 (asin (sin 0.125))))
(test 125.0d0 round (* 1000 (magnitude (asin (sin 0.125+0.0d0i)))))
(test 125.0 round (* 1000 (asin (sin 1/8))))
(test 125.0 round (* 1000 (acos (cos 0.125))))
(test 125.0d0-0.0i z-round (* 1000 (acos (cos 0.125+0.0d0i))))
(test 125.0 round (* 1000 (acos (cos 1/8))))
(test 785.0 round (* 1000 (atan 1 1)))
(test 785.0 round (* 1000 (atan 1.0 1.0)))
(err/rt-test (atan 1.0 1.0+0.0i))
(err/rt-test (atan 1.0+0.0i 1.0))
(test 2356.0 round (* 1000 (atan 1 -1)))
(test -785.0 round (* 1000 (atan -1 1)))
(test 785.0 round (* 1000 (atan 1)))
(test 100.0 round (* 100 (tan (atan 1))))
(test 100.0-0.0i z-round (* 100 (tan (+ +0.0i (atan 1)))))
(test 0.0 atan 0.0 0)
(test 0 atan 0 1)
(test 0 atan 0 (expt 2 100))
(test 0.0 atan 0 1.0)
(test 314.0 round (* 100 (atan 0 -1)))
(err/rt-test (atan 0 0) exn:fail:contract:divide-by-zero?)
(test 1024.0 round (expt 2.0 10.0))
(test 1024.0 round (expt -2.0 10.0))
(test -512.0 round (expt -2.0 9.0))
(test 32.0 round (sqrt 1024.0))
(test 32.0+0.0i z-round (sqrt 1024.0+0.0i))
(test 1.0+1.5e-10i sqrt 1+3e-10i)

(test 1 exp 0)
(test 1.0 exp 0.0)
(test 1.0 exp -0.0)
(test 272.0 round (* 100 (exp 1)))

(test 0 log 1)
(test 0.0 log 1.0)
(test -inf.0 log 0.0)
(test -inf.0 log -0.0)
(test +inf.0 log +inf.0)
(test +inf.0 real-part (log -inf.0))
(test +3142.0 round (* 1000 (imag-part (log -inf.0))))
(test +nan.0 log +nan.0)
(err/rt-test (log 0) exn:fail:contract:divide-by-zero?)

(test 1 cos 0)
(test 1.0 cos 0.0)
(test 0 sin 0)
(test 0.0 sin 0.0)
(test -0.0 sin -0.0)
(test 0 tan 0)
(test 0.0 tan 0.0)
(test -0.0 tan -0.0)

(test #t >= 1 (sin 12345678901234567890123))
(test #t >= 1 (cos 12345678901234567890123))
(test #t <= -inf.0 (tan 12345678901234567890123) +inf.0)

(test 0 atan 0)
(test 0.0 atan 0.0)
(test -0.0 atan -0.0)
(test 314.0 round (* 400 (atan 1)))
(test 314.0 round (* 400 (atan 1.0)))
(test 0 asin 0)
(test 0.0 asin 0.0)
(test -0.0 asin -0.0)
(test 314.0 round (* 200 (asin 1)))
(test 314.0 round (* 200 (asin 1.0)))
(test 0 acos 1)
(test 0.0 acos 1.0)
(test 314.0 round (* 200 (acos 0)))
(test 314.0 round (* 200 (acos 0.0)))
(test 314.0 round (* 200 (acos -0.0)))
(test (/ 314.0 2) round (* 100 (atan +inf.0)))
(test (/ -314.0 2) round (* 100 (atan -inf.0)))

(test 71034.0 round (* 100 (log 312918491891666147403524564598095080760332972643192197862041633988540637438735086398143104076897116667450730097183397289314559387355872839339937813881411504027225774279272518360586167057501686099965513263132778526566297754301647311975918380842568054630540214544682491386730004162058539391336047825248736472519)))
(test 71117.0 round (* 100 (log (expt 2 1026))))
(test 71048.0 round (* 100 (log (expt 2 1025))))
(test 70978.0 round (* 100 (log (expt 2 1024))))
(test 70909.0 round (* 100 (log (expt 2 1023))))
(test 35420.0 round (* 100 (log (expt 2 511))))
(test 35489.0 round (* 100 (log (expt 2 512))))
(test 35558.0 round (* 100 (log (expt 2 513))))
(test 141887.0 round (* 100 (log (expt 2 2047))))
(test 141957.0 round (* 100 (log (expt 2 2048))))
(test 142026.0 round (* 100 (log (expt 2 2049))))
(test 23026.0 round (log (expt 10 10000)))
(test 23026.0 round (real-part (log (- (expt 10 10000)))))
(test 3.0 round (imag-part (log (- (expt 10 10000)))))

(define (test-inf-bad f)
  (test-nan.0 f +inf.0)
  (test-nan.0 f -inf.0)
  (test-nan.0 f +nan.0))

(test-inf-bad tan)
(test-inf-bad sin)
(test-inf-bad cos)
(test-inf-bad asin)
(test-inf-bad acos)

#| dyoo: no support for rationalize
(test 11/7 rationalize (inexact->exact (atan +inf.0 1)) 1/100)
(test -11/7 rationalize (inexact->exact (atan -inf.0 1)) 1/100)
(test 0.0 atan 1 +inf.0)
(test 22/7 rationalize (inexact->exact (atan 1 -inf.0)) 1/100)

; Note on the following tests with atan and inf.0:
;  The IEEE standard makes this decision. I think it's a bad one,
;  since (limit (atan (g x) (f x))) as x -> +inf.0 is not necessarily
;  (atan 1 1) when (limit (f x)) and (limit (g x)) are +inf.0.
;  Perhaps IEEE makes this choice because it's easiest to compute.
(test 7/9 rationalize (inexact->exact (atan +inf.0 +inf.0)) 1/100)
(test 26/11 rationalize (inexact->exact (atan +inf.0 -inf.0)) 1/100)
(test -7/9 rationalize (inexact->exact (atan -inf.0 +inf.0)) 1/100)
|#

(test-nan.0 atan +nan.0)
(test-nan.0 atan 1 +nan.0)
(test-nan.0 atan +nan.0 1)

(test -1178.+173.i  z-round (* 1000 (atan -2+1i)))

(map (lambda (f) 
       (err/rt-test (f "a"))
       (arity-test f 1 1))
     (list log exp asin acos tan))
(err/rt-test (atan "a" 1))
(err/rt-test (atan 2+i 1))
(err/rt-test (atan "a"))
(err/rt-test (atan 1 "a"))
(err/rt-test (atan 1 2+i))
(arity-test atan 1 2)

(test 3166.+1960.i  z-round (* 1000 (sin 1+2i)))
(test -3166.-1960.i  z-round (* 1000 (sin -1-2i)))
(test 0+1175.i z-round (* 1000 (sin 0+i)))
(test -642.-1069.i z-round (* 1000 (cos 2+i)))
(test -642.-1069.i z-round (* 1000 (cos -2-i)))
(test 1543. z-round (* 1000 (cos 0+i)))
(test 272-1084.i z-round (* 1000 (tan 1-i)))
(test -272+1084.i z-round (* 1000 (tan -1+i)))

(test 693.+3142.i z-round (* 1000 (log -2)))
(test 1571.-1317.i z-round (* 1000 (asin 2)))
(test -1571.+1317.i z-round (* 1000 (asin -2)))
(test 0+3688.i z-round (* 1000 (acos 20)))
(test 3142.-3688.i z-round (* 1000 (acos -20)))

(define (cs2 c) (+ (* (cos c) (cos c)) (* (sin c) (sin c))))
(test 0.0 imag-part (cs2 2+3i))
(test 1000.0 round (* 1000 (real-part (cs2 2+3i))))
(test 0.0 imag-part (cs2 -2+3i))
(test 1000.0 round (* 1000 (real-part (cs2 -2+3i))))
(test 0.0 imag-part (cs2 2-3i))
(test 1000.0 round (* 1000 (real-part (cs2 2-3i))))

(test #t positive? (real-part (sqrt (- 1 (* 2+3i 2+3i)))))

(test (- f4.0) round (- f4.5))
(test (- f4.0) round (- f3.5))
(test (- f4.0) round (- f3.9))
(test f0.0 round f0.0)
(test f0.0 round f.25)
(test f1.0 round f0.8)
(test f4.0 round f3.5)
(test f4.0 round f4.5)
(let ((x (string->number "4195835.0"))
      (y (string->number "3145727.0")))
  (test #t 'pentium-fdiv-bug (> f1.0 (- x (* (/ x y) y)))))

#| dyoo: no support for rationalize

(test (exact->inexact 1/3) rationalize .3 1/10)
(test 1/3 rationalize 3/10 1/10)
(test (exact->inexact 1/3) rationalize .3 -1/10)
(test 1/3 rationalize 3/10 -1/10)
(test 0 rationalize 3/10 4/10)
(test 0.0 rationalize .3 4/10)
(err/rt-test (rationalize .3+0.0i 4/10))
(err/rt-test (rationalize .3+0.0i 1/10))

(define (test-rat-inf v)
  (define zero (if (exact? v) 0 0.0))

  (test +inf.0 rationalize +inf.0 v)
  (test -inf.0 rationalize -inf.0 v)
  (test-nan.0 rationalize +nan.0 v)

  (test zero rationalize v +inf.0)
  (test zero rationalize v -inf.0)
  (test-nan.0 rationalize v +nan.0))

(let loop ([i 100])
  (unless (= i -100)
	  (test (/ i 100) rationalize (inexact->exact (/ i 100.0)) 1/100000)
	  (loop (sub1 i))))

(arity-test rationalize 2 2)
|#

(define tb
  (lambda (n1 n2)
    (= n1 (+ (* n2 (quotient n1 n2))
	     (remainder n1 n2)))))


(test -2147483648 - 2147483648)
(test 2147483648 - -2147483648)
(test #f = -2147483648 2147483648)
(test #t = -2147483648 -2147483648)
(test #t = 2147483648 2147483648)
(test 2147483647 sub1 2147483648)
(test 2147483648 add1 2147483647)
(test 2147483648 * 1 2147483648)

(test 437893890380859375 expt 15 15)

(test 0 modulo -2177452800 86400)
(test 0 modulo 2177452800 -86400)
(test 0 modulo 2177452800 86400)
(test 0 modulo -2177452800 -86400)

(test 86399 modulo -2177452801 86400)
(test -1 modulo 2177452799 -86400)
(test 1 modulo 2177452801 86400)
(test -86399 modulo -2177452799 -86400)

(test #t 'remainder (tb 281474976710655 65535))
(test #t 'remainder (tb 281474976710654 65535))
(test 281474976710655 string->number "281474976710655")
(test "281474976710655" number->string 281474976710655)
(test "-4" number->string -4 16)
(test "-e" number->string -14 16)
(test "0" number->string 0 16)
(test "30000000" number->string #x30000000 16)


(test "0" number->string 0)
(test "100" number->string 100)
(test "100" number->string 256 16)
(test 256 string->number "100" 16)
(test 15 string->number "#o17")
(test 15 string->number "#o17" 10)

(require "numstrs.rkt")
(let loop ([l number-table])
  (unless (null? l)
	  (let* ([pair (car l)]
		 [v (car pair)]
		 [v (if (or (eq? v 'X)
			    (symbol? v)
			    (eof-object? v))
			#f 
			v)]
		 [s (cadr pair)])
	    (test v string->number s))
	  (loop (cdr l))))

;; Test special inexact names in complex combinations:
(let ([parts '(+inf.0 -inf.0 +nan.0 1 0 0.0 1/2)])
  (for-each
   (lambda (a)
     (for-each
      (lambda (b)
	(let ([rect (format "~a~a~ai"
			    a
			    (if (member b '(+inf.0 -inf.0 +nan.0))
				""
				"+")
			    b)]
	      [polar (format "~a@~a" a b)])
	  (test (make-rectangular a b) string->number rect)
	  (test (make-polar a b) string->number polar)))
      parts))
   parts)

  (for-each
   (lambda (a)
     (let ([rect1 (format "~a+1/0i" a)]
	   [rect2 (format "1/0~a~ai"
			  (if (member a '(+inf.0 -inf.0 +nan.0))
			      ""
			      "+")
			  a)]
	   [polar1 (format "~a@1/0" a)]
	   [polar2 (format "1/0@~a" a)]

           ;; dyoo: currently disabled: no support for read
	   #;[dbz-test (lambda (s)
		       (test 'div 'divide-by-zero
			     (with-handlers ([(lambda (x)
						(and (exn:fail:read? x)
						     (regexp-match "division by zero" 
								   (exn-message x))))
					      (lambda (x) 'div)])
			       (read (open-input-string s)))))])
       (test #f string->number rect1)
       (test #f string->number rect2)
       (test #f string->number polar1)
       (test #f string->number polar2)
       ;; dyoo: no support for read
       #;(dbz-test rect1)
       #;(dbz-test rect2)
       #;(dbz-test polar1)
       #;(dbz-test polar2)))
   parts))

(test #f string->number "88" 7)
(test #f string->number "")
(test #f string->number " 1")
(test #f string->number ".")
(test #f string->number "#4@#i5")
(test #f string->number "190888 qwerqwerq")
(test #t symbol? '1/x)
(test #t symbol? '1+ei)
(test #t symbol? '|1/0|)

(test #t inexact? (string->number "4@5"))
(test #f inexact? (string->number "#e4@5"))
(test #f inexact? (string->number "#e4.0@5.0"))

(arity-test string->number 1 2)
(arity-test number->string 1 2)

(err/rt-test (number->string 'a))
(err/rt-test (number->string 1 'a))
(err/rt-test (number->string 'a 10))
(err/rt-test (number->string 1.8 8) exn:application:mismatch?)
(err/rt-test (number->string 1 -1))

(err/rt-test (string->number 'a))
(err/rt-test (string->number 'a 'a))
(err/rt-test (string->number "12" -1))
(err/rt-test (string->number "12" 17))
(err/rt-test (string->number "1" "1"))
(err/rt-test (string->number 1 1))

(test #t andmap (lambda (x) (and (>= x 0) (< x 10))) (map random '(10 10 10 10)))
;; dyoo: no support for random-seed
#;(test (void) random-seed 5)
#;(test (begin (random-seed 23) (list (random 10) (random 20) (random 30)))
      'random-seed-same
      (begin (random-seed 23) (list (random 10) (random 20) (random 30))))
#;(arity-test random-seed 1 1)
(arity-test random 0 2)
#|
(err/rt-test (random-seed "apple"))
(err/rt-test (random-seed 4.5))
(err/rt-test (random-seed -1))
(err/rt-test (random-seed (expt 2 31)))
(err/rt-test (random-seed big-num))
|#
(err/rt-test (random "apple"))
(err/rt-test (random 0))
(err/rt-test (random -6))
(err/rt-test (random 4294967088))
(err/rt-test (random (expt 2 32)))
(err/rt-test (random big-num))

#| dyoo: random seed disabled for now
(random-seed 101)
(define x (list (random 10) (random 20) (random 30)))
(random-seed 101)
(parameterize ([current-pseudo-random-generator (make-pseudo-random-generator)])
  (random 10)
  (random 10))
(test x 'generator-preserved (list (random 10) (random 20) (random 30)))
(random-seed 101)
(thread-wait (thread (lambda ()
		       (random 10)
		       (random 10))))
(test #f 'generator-not-preserved (equal? x (list (random 10) (random 20) (random 30))))
(test #t pseudo-random-generator? (make-pseudo-random-generator))
(test #t pseudo-random-generator? (current-pseudo-random-generator))
(test #t pseudo-random-generator? (current-evt-pseudo-random-generator))
(test #f pseudo-random-generator? 10)
(arity-test pseudo-random-generator? 1 1)
(arity-test make-pseudo-random-generator 0 0)
(arity-test current-pseudo-random-generator 0 1)
(arity-test current-evt-pseudo-random-generator 0 1)
(err/rt-test (current-pseudo-random-generator 10))
|#

(test #t = 0 0)
(test #f = 0 (expt 2 32))
(test #f = (expt 2 32) 0)
(test #f = (- (expt 2 32)) (expt 2 32))
(test #f = (expt 2 32) (- (expt 2 32)))
(test #t = 1234567890987654321 1234567890987654321)

(test #f < 0 0)
(test #t < 0 (expt 2 32))
(test #f < (expt 2 32) 0)
(test #t < (- (expt 2 32)) 0)
(test #f < 0 (- (expt 2 32)))
(test #f < 1234567890987654321 1234567890987654321)
(test #t < (- (expt 3 64)) (- (expt 2 13)))
(test #f < (- (expt 2 13)) (- (expt 3 64)))
(test #t < (- 123456789876543200) 123456789876543200)
(test #f < 123456789876543200 (- 123456789876543200))

(test 1234567890987654321 + 1234567890987654321 0)
(test 1234567890987654321 + 0 1234567890987654321)
(test 1234567890987654321 - 1234567890987654321 0)
(test -1234567890987654321 - 0 1234567890987654321)
(test (expt 2 33) + (expt 2 32) (expt 2 32))
(test 0 - (expt 2 32) (expt 2 32))
(test (expt 2 31) - (expt 2 32) (expt 2 31))
(test (- (expt 2 31)) - (expt 2 31) (expt 2 32))
(test 18446744073709551621 + 18446744073709551615 6)
(test 18446744073709551621 + 6 18446744073709551615)
(test 0 - #xfffffffffffffffff #xfffffffffffffffff)
(test -1 - #xffffffffffffffffe #xfffffffffffffffff)
(test 1 - #xfffffffffffffffff #xffffffffffffffffe)
(test #x1000000000000000000000000 + #xffffffffffffffffffffffff 1)

(test 0 * 1234567890987654321 0)
(test 0 * 0 1234567890987654321)
(test #x100000000000000000000 * #x100000000000 #x1000000000)
(test #x-100000000000000000000 * #x100000000000 #x-1000000000)
(test #x100000000000000000000 * #x-100000000000 #x-1000000000)
(test #x-100000000000000000000 * #x-100000000000 #x1000000000)
(test #x100000000000000000000 * #x1000000000 #x100000000000)
(test #x-100000000000000000000 * #x1000000000 #x-100000000000)
(test #x100000000000000000000 * #x-1000000000 #x-100000000000)
(test #x-100000000000000000000 * #x-1000000000 #x100000000000)
(test 4521191813415169 * #x100000000001 #x101)
(test 4521191813415169 * #x101 #x100000000001)

(test (expt 2 35) * (expt 2 32) 8)
(test (- (expt 2 35)) * (- (expt 2 32)) 8)
(test (- (expt 2 35)) * (expt 2 32) -8)
(test (expt 2 35) * (- (expt 2 32)) -8)
(test (- (add1 (expt 2 128)) (expt 2 65)) * (sub1 (expt 2 64)) (sub1 (expt 2 64)))

(test 4294967296 expt 2 32)
(test 3433683820292512484657849089281 expt 3 64)
(test 8192 expt 2 13)
(test 8589934592 expt 2 33)
(test 2147483648 expt 2 31)
(test 34359738368 expt 2 35)
(test 36893488147419103232 expt 2 65)
(test 18446744073709551616 expt 2 64)
(test 340282366920938463463374607431768211456 expt 2 128)
(test 340282366920938463463374607431768211456 expt -2 128)
(test 174449211009120179071170507 expt 3 55)
(test -174449211009120179071170507 expt -3 55)
(test 59768263894155949306790119265585619217025149412430681649 expt 7 66)
(test 1 expt 1234567890987654321 0)
(test 0 expt 0 1234567890987654321)
(test 1 expt 1 1234567890987654321)
(test 1234567890987654321 expt 1234567890987654321 1)
(test 828179745220145502584084235957368498016122811853894435464201864103254919330121223037770283296858019385573376 expt 953962166440690129601298432 4)

#| dyoo: bitwise operations disabled 
(test 0 bitwise-and 0 1234567890987654321)
(test 0 bitwise-and 1234567890987654321 0)
(test 0 bitwise-and -1234567890987654321 0)
(test 0 bitwise-and 0 -1234567890987654321)
(test 1234567890987654321 bitwise-and -1 1234567890987654321)
(test 1234567890987654321 bitwise-and 1234567890987654321 -1)
(test -1234567890987654321 bitwise-and -1 -1234567890987654321)
(test -1234567890987654321 bitwise-and -1234567890987654321 -1)
(test 19687594650088321058936321 bitwise-and (expt 3 55) (expt 7 66))
(test 59768263894155949306790119265565931622375061091371745329 bitwise-and (- (expt 3 55)) (expt 7 66))
(test 154761616359031858012234187 bitwise-and (expt 3 55) (- (expt 7 66)))
(test -59768263894155949306790119265740380833384181270442915835 bitwise-and (- (expt 3 55)) (- (expt 7 66)))
(test 19687594650088321058936321 bitwise-and (expt 7 66) (expt 3 55))
(test 59768263894155949306790119265565931622375061091371745329 bitwise-and (expt 7 66) (- (expt 3 55)))
(test 154761616359031858012234187 bitwise-and (- (expt 7 66)) (expt 3 55))
(test -59768263894155949306790119265740380833384181270442915835 bitwise-and (- (expt 7 66)) (- (expt 3 55)))
(test #x-10000000000000000 bitwise-and #x-100000000 #x-ffffffff00000001)
(test -9223372036854775808 bitwise-and (- (expt 2 31)) (- (expt 2 63)))
(test -57896044618658097711785492504343953926634992332820282019728792003956564819968 bitwise-and (- (expt 2 127)) (- (expt 2 255)))
(test -115792089237316195423570985008687907853269984665640564039457584007913129639936 bitwise-and (- (expt 2 128)) (- (expt 2 256)))
(test 0 bitwise-and #x10101010101010101010101010 #x1010101010101010101010101)
(test 0 bitwise-and #x10101010101010101010101010 #x101010101)
(test #xf0000000 bitwise-and #x101010101010101010f0101010 #xf1010101)

(test 1234567890987654321 bitwise-ior 0 1234567890987654321)
(test 1234567890987654321 bitwise-ior 1234567890987654321 0)
(test -1234567890987654321 bitwise-ior -1234567890987654321 0)
(test -1234567890987654321 bitwise-ior 0 -1234567890987654321)
(test -1 bitwise-ior -1 1234567890987654321)
(test -1 bitwise-ior 1234567890987654321 -1)
(test -1 bitwise-ior -1 -1234567890987654321)
(test -1 bitwise-ior -1234567890987654321 -1)
(test -1 bitwise-ior #x-100000000 #x-ffffffff00000001)
(test 59768263894155949306790119265740380833384181270442915835 bitwise-ior (expt 3 55) (expt 7 66))
(test -154761616359031858012234187 bitwise-ior (- (expt 3 55)) (expt 7 66))
(test -59768263894155949306790119265565931622375061091371745329 bitwise-ior (expt 3 55) (- (expt 7 66)))
(test -19687594650088321058936321 bitwise-ior (- (expt 3 55)) (- (expt 7 66)))
(test 59768263894155949306790119265740380833384181270442915835 bitwise-ior (expt 7 66) (expt 3 55))
(test -154761616359031858012234187 bitwise-ior (expt 7 66) (- (expt 3 55)))
(test -59768263894155949306790119265565931622375061091371745329 bitwise-ior (- (expt 7 66)) (expt 3 55))
(test -19687594650088321058936321 bitwise-ior (- (expt 7 66)) (- (expt 3 55)))
(test 9223372039002259456 bitwise-ior (expt 2 31) (expt 2 63))
(test #xf000000f bitwise-ior #xf0000000 #x0000000f)
(test -15 bitwise-ior #xf0000000 #x-f000000f)
(test #x-100000000 bitwise-ior #x-100000000 #x-1000000000000)
(test #x-10000000000000000 bitwise-ior #x-10000000000000000 #x-10000000000000000)
(test #x-100000000 bitwise-ior #xffff00000000 #x-1000000000000)
(test #x-ffffffff bitwise-ior #x-100000000 1)

(test 1234567890987654321 bitwise-xor 0 1234567890987654321)
(test 1234567890987654321 bitwise-xor 1234567890987654321 0)
(test -1234567890987654321 bitwise-xor -1234567890987654321 0)
(test -1234567890987654321 bitwise-xor 0 -1234567890987654321)
(test -1234567890987654322 bitwise-xor -1 1234567890987654321)
(test -1234567890987654322 bitwise-xor 1234567890987654321 -1)
(test 1234567890987654320 bitwise-xor -1 -1234567890987654321)
(test 1234567890987654320 bitwise-xor -1234567890987654321 -1)
(test 59768263894155949306790119265720693238734092949383979514 bitwise-xor (expt 3 55) (expt 7 66))
(test -59768263894155949306790119265720693238734092949383979516 bitwise-xor (- (expt 3 55)) (expt 7 66))
(test -59768263894155949306790119265720693238734092949383979516 bitwise-xor (expt 3 55) (- (expt 7 66)))
(test 59768263894155949306790119265720693238734092949383979514 bitwise-xor (- (expt 3 55)) (- (expt 7 66)))
(test 59768263894155949306790119265720693238734092949383979514 bitwise-xor (expt 7 66) (expt 3 55))
(test -59768263894155949306790119265720693238734092949383979516 bitwise-xor (expt 7 66) (- (expt 3 55)))
(test -59768263894155949306790119265720693238734092949383979516 bitwise-xor (- (expt 7 66)) (expt 3 55))
(test 59768263894155949306790119265720693238734092949383979514 bitwise-xor (- (expt 7 66)) (- (expt 3 55)))
(test #xffffffffffffffff bitwise-xor #xf0f0f0f0f0f0f0f0 #x0f0f0f0f0f0f0f0f)
(test #x-ffffffffffffffff bitwise-xor #xf0f0f0f0f0f0f0f0 #x-0f0f0f0f0f0f0f0f)
(test #xffffffffffffffe1 bitwise-xor #x-f0f0f0f0f0f0f0f0 #x-0f0f0f0f0f0f0f0f)
(test #x-ffffffffffffffe1 bitwise-xor #x-f0f0f0f0f0f0f0f0 #x0f0f0f0f0f0f0f0f)
(test 0 bitwise-xor #xff00ff00ff00 #xff00ff00ff00)
(test 1 bitwise-xor #xff00ff00ff00 #xff00ff00ff01)

(test -1 bitwise-not 0)
(test -2 bitwise-not 1)
(test 0 bitwise-not -1)
(test -170141183460469231731687303715884105729 bitwise-not (expt 2 127))
(test -115792089237316195423570985008687907853269984665640564039457584007913129639937 bitwise-not (expt 2 256))
(test 170141183460469231731687303715884105727 bitwise-not (- (expt 2 127)))
(test 115792089237316195423570985008687907853269984665640564039457584007913129639935 bitwise-not (- (expt 2 256)))
(test -6495847189879200919523571558866128178519676272281183726839381003906688615833519556218736219093975317609794137607877958572218335473711513642939050 bitwise-not (expt 13 130))
(test 6495847189879200919523571558866128178519676272281183726839381003906688615833519556218736219093975317609794137607877958572218335473711513642939048 bitwise-not (- (expt 13 130)))
(test #x40000000 bitwise-not #x-40000001)

(test 1234567890987654321 arithmetic-shift 1234567890987654321 0)
(test -1234567890987654321 arithmetic-shift -1234567890987654321 0)
(test (expt 2 32) arithmetic-shift (expt 2 31) 1)
(test (expt 2 256) arithmetic-shift (expt 2 128) 128)
(test (expt 2 277) arithmetic-shift (expt 2 125) 152)
(test (- (expt 2 256)) arithmetic-shift (- (expt 2 128)) 128)
(test (- (expt 2 277)) arithmetic-shift (- (expt 2 125)) 152)
(test (* (expt 13 55) (expt 2 97)) arithmetic-shift (expt 13 55) 97)
(test (* (- (expt 13 55)) (expt 2 97)) arithmetic-shift (- (expt 13 55)) 97)
(test 0 arithmetic-shift 1234567890987654321 -10000)
(test -1 arithmetic-shift -1234567890987654321 -10000)
(test (quotient (expt 13 55) (expt 2 100)) arithmetic-shift (expt 13 55) -100)
(test (quotient (expt 13 55) (expt 2 128)) arithmetic-shift (expt 13 55) -128)
(test (expt 2 13) arithmetic-shift (expt 2 256) -243)
(test (sub1 (quotient (- (expt 13 55)) (expt 2 100))) arithmetic-shift (- (expt 13 55)) -100)
(test (sub1 (quotient (- (expt 13 55)) (expt 2 128))) arithmetic-shift (- (expt 13 55)) -128)
(test (- (expt 2 13)) arithmetic-shift (- (expt 2 256)) -243)
(test #x100000000 arithmetic-shift #x200000000 -1)
(test #x200000000 arithmetic-shift #x100000000 1)

|#


(test "0" number->string 0)
(test "1" number->string 1)
(test "-1" number->string -1)
(test "7284132478923046920834523467890234589203467590267382904573942345703" number->string 7284132478923046920834523467890234589203467590267382904573942345703)
(test "-7284132478923046920834523467890234589203467590267382904573942345703" number->string -7284132478923046920834523467890234589203467590267382904573942345703)
(test "1000101001010101011111011000101001011011100111110001111111010101000100010110001001011011101111011001111101000100110100010101111001111001001011111001000100111000011111110010101010110110001011011111101110000001010111111100111" number->string 7284132478923046920834523467890234589203467590267382904573942345703 2)
(test "-1000101001010101011111011000101001011011100111110001111111010101000100010110001001011011101111011001111101000100110100010101111001111001001011111001000100111000011111110010101010110110001011011111101110000001010111111100111" number->string -7284132478923046920834523467890234589203467590267382904573942345703 2)
(test "105125373051334761772504261133573175046425717113710470376252661337560127747" number->string 7284132478923046920834523467890234589203467590267382904573942345703 8)
(test "-105125373051334761772504261133573175046425717113710470376252661337560127747" number->string -7284132478923046920834523467890234589203467590267382904573942345703 8)
(test "452abec52dcf8fea88b12ddecfa268af3c97c89c3f955b16fdc0afe7" number->string 7284132478923046920834523467890234589203467590267382904573942345703 16)
(test "-452abec52dcf8fea88b12ddecfa268af3c97c89c3f955b16fdc0afe7" number->string -7284132478923046920834523467890234589203467590267382904573942345703 16)
(test "115792089237316195423570985008687907853269984665640564039457584007913129639936" number->string (expt 2 256))
(test "115792089237316195423570985008687907853269984665640564039457584007913129639935" number->string (sub1 (expt 2 256)))
(test "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" number->string (expt 2 256) 2)
(test "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" number->string (sub1 (expt 2 256)) 2)
(test "20000000000000000000000000000000000000000000000000000000000000000000000000000000000000" number->string (expt 2 256) 8)
(test "17777777777777777777777777777777777777777777777777777777777777777777777777777777777777" number->string (sub1 (expt 2 256)) 8)
(test "10000000000000000000000000000000000000000000000000000000000000000" number->string (expt 2 256) 16)
(test "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" number->string (sub1 (expt 2 256)) 16)
(test "-115792089237316195423570985008687907853269984665640564039457584007913129639936" number->string (- (expt 2 256)))
(test "-115792089237316195423570985008687907853269984665640564039457584007913129639935" number->string (- (sub1 (expt 2 256))))
(test "-10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" number->string (- (expt 2 256)) 2)
(test "-1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" number->string (- (sub1 (expt 2 256))) 2)
(test "-20000000000000000000000000000000000000000000000000000000000000000000000000000000000000" number->string (- (expt 2 256)) 8)
(test "-17777777777777777777777777777777777777777777777777777777777777777777777777777777777777" number->string (- (sub1 (expt 2 256))) 8)
(test "-10000000000000000000000000000000000000000000000000000000000000000" number->string (- (expt 2 256)) 16)
(test "-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" number->string (- (sub1 (expt 2 256))) 16)


(test 0 string->number "0")
(test 1 string->number "1")
(test -1 string->number "-1")
(test 7284132478923046920834523467890234589203467590267382904573942345703 string->number "7284132478923046920834523467890234589203467590267382904573942345703")
(test -7284132478923046920834523467890234589203467590267382904573942345703 string->number "-7284132478923046920834523467890234589203467590267382904573942345703")
(test 7284132478923046920834523467890234589203467590267382904573942345703 string->number "1000101001010101011111011000101001011011100111110001111111010101000100010110001001011011101111011001111101000100110100010101111001111001001011111001000100111000011111110010101010110110001011011111101110000001010111111100111" 2)
(test -7284132478923046920834523467890234589203467590267382904573942345703 string->number "-1000101001010101011111011000101001011011100111110001111111010101000100010110001001011011101111011001111101000100110100010101111001111001001011111001000100111000011111110010101010110110001011011111101110000001010111111100111" 2)
(test  7284132478923046920834523467890234589203467590267382904573942345703 string->number "105125373051334761772504261133573175046425717113710470376252661337560127747" 8)
(test -7284132478923046920834523467890234589203467590267382904573942345703 string->number "-105125373051334761772504261133573175046425717113710470376252661337560127747" 8)
(test 7284132478923046920834523467890234589203467590267382904573942345703 string->number "452abec52dcf8fea88b12ddecfa268af3c97c89c3f955b16fdc0afe7" 16)
(test -7284132478923046920834523467890234589203467590267382904573942345703 string->number "-452abec52dcf8fea88b12ddecfa268af3c97c89c3f955b16fdc0afe7" 16)
(test (expt 2 256) string->number "115792089237316195423570985008687907853269984665640564039457584007913129639936")
(test (sub1 (expt 2 256)) string->number "115792089237316195423570985008687907853269984665640564039457584007913129639935")
(test (expt 2 256) string->number "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" 2)
(test (sub1 (expt 2 256)) string->number "1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" 2)
(test (expt 2 256) string->number "20000000000000000000000000000000000000000000000000000000000000000000000000000000000000" 8)
(test (sub1 (expt 2 256)) string->number "17777777777777777777777777777777777777777777777777777777777777777777777777777777777777" 8)
(test (expt 2 256) string->number "10000000000000000000000000000000000000000000000000000000000000000" 16)
(test (sub1 (expt 2 256)) string->number "ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 16)
(test (- (expt 2 256)) string->number "-115792089237316195423570985008687907853269984665640564039457584007913129639936")
(test (- (sub1 (expt 2 256))) string->number "-115792089237316195423570985008687907853269984665640564039457584007913129639935")
(test (- (expt 2 256)) string->number "-10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000" 2)
(test (- (sub1 (expt 2 256))) string->number "-1111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111" 2)
(test (- (expt 2 256)) string->number "-20000000000000000000000000000000000000000000000000000000000000000000000000000000000000" 8)
(test (- (sub1 (expt 2 256))) string->number "-17777777777777777777777777777777777777777777777777777777777777777777777777777777777777" 8)
(test (- (expt 2 256)) string->number "-10000000000000000000000000000000000000000000000000000000000000000" 16)
(test (- (sub1 (expt 2 256))) string->number "-ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff" 16)
(test #f string->number "144r" 10)
(err/rt-test (string->number "10" 30))

(define (q-test quotient)
  (test 0 quotient 0 12345678909876532341)
  (test 0 quotient 0 -1235782934075829307)
  (test 2374865902374859023745 quotient 2374865902374859023745 1)
  (test -2374865902374859023745 quotient -2374865902374859023745 1)
  (test 0 quotient 1 13748910785903278450)
  (test 1 quotient 13748910785903278450 13748910785903278449)
  (test 0 quotient 13748910785903278450 13748910785903278451)
  (test -1 quotient -13748910785903278450 13748910785903278449)
  (test 0 quotient -13748910785903278450 13748910785903278451)
  (test -1 quotient 13748910785903278450 -13748910785903278449)
  (test 0 quotient 13748910785903278450 -13748910785903278451)
  (test 1 quotient -13748910785903278450 -13748910785903278449)
  (test 0 quotient -13748910785903278450 -13748910785903278451)
  (test 1 quotient 13748910785903278450 13748910785903278450)
  (test -1 quotient -13748910785903278450 13748910785903278450)
  (test -1 quotient 13748910785903278450 -13748910785903278450)
  (test 1 quotient -13748910785903278450 -13748910785903278450)
  (test (expt 5 64) quotient (expt 5 256) (expt 5 192))
  (test 0 quotient (expt 5 192) (expt 5 256))
  (test 8636168555094444625386351862800399571116000364436281385023703470168591803162427057971507503472288226560547293946149 quotient (expt 5 192) (expt 2 64)))
(q-test quotient)
;; dyoo: no support for quotient/remainder
#;(q-test (lambda (n1 n2) (let-values ([(q r) (quotient/remainder n1 n2)]) q)))

(define (r-test remainder)
  (test 0 remainder 0 12345678909876532341)
  (test 0 remainder 0 -1235782934075829307)
  (test 0 remainder 2374865902374859023745 1)
  (test 0 remainder -2374865902374859023745 1)
  (test 1 remainder 1 13748910785903278450)
  (test 1 remainder 13748910785903278450 13748910785903278449)
  (test 13748910785903278450 remainder 13748910785903278450 13748910785903278451)
  (test -1 remainder -13748910785903278450 13748910785903278449)
  (test -13748910785903278450 remainder -13748910785903278450 13748910785903278451)
  (test 1 remainder 13748910785903278450 -13748910785903278449)
  (test 13748910785903278450 remainder 13748910785903278450 -13748910785903278451)
  (test -1 remainder -13748910785903278450 -13748910785903278449)
  (test -13748910785903278450 remainder -13748910785903278450 -13748910785903278451)
  (test 0 remainder 13748910785903278450 13748910785903278450)
  (test 0 remainder -13748910785903278450 13748910785903278450)
  (test 0 remainder 13748910785903278450 -13748910785903278450)
  (test 0 remainder -13748910785903278450 -13748910785903278450)
  (test 0 remainder (expt 5 256) (expt 5 192))
  (test (expt 5 192) remainder (expt 5 192) (expt 5 256))
  (test 12241203936672963841 remainder (expt 5 192) (expt 2 64)))
(r-test remainder)
;; dyoo: no support for quotient/remainder
#;(r-test (lambda (n1 n2) (let-values ([(q r) (quotient/remainder n1 n2)]) r)))

(define (s-test sqrt)
  (test 0 sqrt 0)
  (test 1 sqrt 1)
  (test 2 sqrt 4)
  (test 3 sqrt 9)
  (test (expt 2 64) sqrt (* (expt 2 64) (expt 2 64)))
  (test (expt 13 70) sqrt (* (expt 13 70) (expt 13 70)))
  (test (sub1 (expt 2 200)) sqrt (* (sub1 (expt 2 200)) (sub1 (expt 2 200))))
  (test (expt 2 25) sqrt (expt 2 50))
  (test 1 sqrt 3)
  (test #xffffffff sqrt (sub1 (expt 2 64)))
  (test 2876265888493261300027370452880859375 sqrt (expt 15 62))
  (test #x8f0767e50d4d0c07563bd81f530d36 sqrt (expt 15 61)))
(s-test integer-sqrt)

;; dyoo: no support for integer-sqrt/remainder
#;(s-test (lambda (a) (let-values ([(root rem) (integer-sqrt/remainder a)]) root)))

(define (sr-test sqrt)
  (test 0 sqrt 0)
  (test 0 sqrt 1)
  (test 0 sqrt 4)
  (test 0 sqrt 9)
  (test 0 sqrt (* (expt 2 64) (expt 2 64)))
  (test 0 sqrt (* (expt 13 70) (expt 13 70)))
  (test 0 sqrt (* (sub1 (expt 2 200)) (sub1 (expt 2 200))))
  (test 0 sqrt (expt 2 50))
  (test 2 sqrt 3)
  (test 8589934590 sqrt (sub1 (expt 2 64)))
  (test 0 sqrt (expt 15 62))
  (test 1306106749204831357295958563982718571 sqrt (expt 15 61)))
;; dyoo: no support for integer-sqrt/remainder
#;(sr-test (lambda (a) (let-values ([(root rem) (integer-sqrt/remainder a)]) rem)))

(test 1.7320508075688772 sqrt 3)
(test 4294967296.0 sqrt (sub1 (expt 2 64)))
(test 2876265888493261300027370452880859375 sqrt (expt 15 62))
(test 7.426486590265921e+35 sqrt (expt 15 61))



(test 5.515270307539953e+71 exact->inexact (expt 15 61))
(test -5.515270307539953e+71 exact->inexact (- (expt 15 61)))
(test 1.8446744073709552e+19 exact->inexact (expt 2 64))
(test 1.157920892373162e+77 exact->inexact (expt 2 256))
(test 1.157920892373162e+77 exact->inexact (sub1 (expt 2 256)))

(test 551527030753995340375346347667240734743269800540264151034260072897183744 inexact->exact 5.515270307539953d+71)
(test (expt 2 64) inexact->exact 1.8446744073709552e+19)
(test (- (expt 2 64)) inexact->exact -1.8446744073709552e+19)
(test (expt 2 256) inexact->exact 1.157920892373162d+77)
(test 115792089237316195423570985008687907853269984665640564039457584007913129639936 inexact->exact 1.157920892373162d+77)

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

#| dyoo: no support for integer-bytes->integer
(test (integer-bytes->integer #"\1\2" #f) integer-bytes->integer #"\1\2" #f (system-big-endian?))

(define (test-integer-bytes->integer integer-bytes->integer)
  (test 0 integer-bytes->integer #"\0\0" #t)
  (test -1 integer-bytes->integer #"\377\377" #t)
  (test 65535 integer-bytes->integer #"\377\377" #f)
  ;;
  (test 0 integer-bytes->integer #"\0\0" #t #t)
  (test -1 integer-bytes->integer #"\377\377" #t #t)
  (test 65535 integer-bytes->integer #"\377\377" #f #t)
  (test -256 integer-bytes->integer #"\377\0" #t #t)
  (test -255 integer-bytes->integer #"\377\1" #t #t)
  (test 511 integer-bytes->integer #"\1\377" #t #t)
  (test 513 integer-bytes->integer #"\1\2" #f #f)
  ;;
  (test 0 integer-bytes->integer #"\0\0" #t #f)
  (test -1 integer-bytes->integer #"\377\377" #t #f)
  (test 65535 integer-bytes->integer #"\377\377" #f #f)
  (test 511 integer-bytes->integer #"\377\1" #t #f)
  (test -255 integer-bytes->integer #"\1\377" #t #f)
  (test 258 integer-bytes->integer #"\1\2" #f #t)

  (test 0 integer-bytes->integer #"\0\0\0\0" #t)
  (test -1 integer-bytes->integer #"\377\377\377\377" #t)
  (test 4294967295 integer-bytes->integer #"\377\377\377\377" #f)
  ;;
  (test 0 integer-bytes->integer #"\0\0\0\0" #t #t)
  (test -1 integer-bytes->integer #"\377\377\377\377" #t #t)
  (test 4294967295 integer-bytes->integer #"\377\377\377\377" #f #t)
  (test -16777216 integer-bytes->integer #"\377\0\0\0" #t #t)
  (test 255 integer-bytes->integer #"\0\0\0\377" #t #t)
  ;;
  (test 0 integer-bytes->integer #"\0\0\0\0" #t #f)
  (test -1 integer-bytes->integer #"\377\377\377\377" #t #f)
  (test 4294967295 integer-bytes->integer #"\377\377\377\377" #f #f)
  (test 16777471 integer-bytes->integer #"\377\0\0\1" #t #f)
  (test -16777216 integer-bytes->integer #"\0\0\0\377" #t #f)
  (test -16777215 integer-bytes->integer #"\1\0\0\377" #t #f)

  (test 1835103348 integer-bytes->integer #"matt" #t #t)
  (test 1953784173 integer-bytes->integer #"matt" #t #f)

  (test 0 integer-bytes->integer #"\0\0\0\0\0\0\0\0" #t #t)
  (test -1 integer-bytes->integer #"\377\377\377\377\377\377\377\377" #t #f)
  (test 18446744073709551615 integer-bytes->integer #"\377\377\377\377\377\377\377\377" #f #f)
  (test 4294967295 integer-bytes->integer #"\377\377\377\377\0\0\0\0" #t #f)
  (test -4294967296 integer-bytes->integer #"\0\0\0\0\377\377\377\377" #t #f)
  (test 8589934591 integer-bytes->integer #"\377\377\377\377\1\0\0\0" #t #f)
  (test -4294967295 integer-bytes->integer #"\1\0\0\0\377\377\377\377" #t #f)
  ;;
  (test 0 integer-bytes->integer #"\0\0\0\0\0\0\0\0" #t #f)
  (test -1 integer-bytes->integer #"\377\377\377\377\377\377\377\377" #t #f)
  (test 18446744073709551615 integer-bytes->integer #"\377\377\377\377\377\377\377\377" #f #f)
  (test -4294967296 integer-bytes->integer #"\377\377\377\377\0\0\0\0" #t #t)
  (test 4294967295 integer-bytes->integer #"\0\0\0\0\377\377\377\377" #t #t)
  (test -4294967295 integer-bytes->integer #"\377\377\377\377\0\0\0\1" #t #t)
  (test 8589934591 integer-bytes->integer #"\0\0\0\1\377\377\377\377" #t #t))

(test-integer-bytes->integer integer-bytes->integer)
(test-integer-bytes->integer (lambda (bstr signed? [big-endian? (system-big-endian?)])
                               (integer-bytes->integer (bytes-append #"xxx" bstr)
                                                       signed?
                                                       big-endian?
                                                       3)))
(test-integer-bytes->integer (lambda (bstr signed? [big-endian? (system-big-endian?)])
                               (integer-bytes->integer (bytes-append #"xxx" bstr #"x")
                                                       signed?
                                                       big-endian?
                                                       3
                                                       (+ 3 (bytes-length bstr)))))

(arity-test integer-bytes->integer 2 5)
(err/rt-test (integer-bytes->integer 'ok #t))
(err/rt-test (integer-bytes->integer #"" #t))
(err/rt-test (integer-bytes->integer #"a" #t))
(err/rt-test (integer-bytes->integer #"abc" #t))
(err/rt-test (integer-bytes->integer #"abcdefghi" #t))
(err/rt-test (integer-bytes->integer #"abcdefghi" #t #f 0 3))
(err/rt-test (integer-bytes->integer #"abcd" #t #f 1))

;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(test (integer->integer-bytes 42 2 #f) integer->integer-bytes 42 2 #f (system-big-endian?))

(define (test-integer->integer-bytes integer->integer-bytes)
  (test #"\0\0" integer->integer-bytes 0 2 #t)
  (test #"\377\377" integer->integer-bytes -1 2 #t)
  (test #"\377\377" integer->integer-bytes 65535 2 #f)
  ;;
  (test #"\0\0" integer->integer-bytes 0 2 #t #t)
  (test #"\377\377" integer->integer-bytes -1 2 #t #t)
  (test #"\377\377" integer->integer-bytes 65535 2 #f #t)
  (test #"\377\0" integer->integer-bytes -256 2 #t #t)
  (test #"\377\1" integer->integer-bytes -255 2 #t #t)
  (test #"\1\377" integer->integer-bytes 511 2 #t #t)
  (test #"\1\2" integer->integer-bytes 513 2 #f #f)
  ;;
  (test #"\0\0" integer->integer-bytes 0 2 #t #f)
  (test #"\377\377" integer->integer-bytes -1 2 #t #f)
  (test #"\377\377" integer->integer-bytes 65535 2 #f #f)
  (test #"\377\1" integer->integer-bytes 511 2 #t #f)
  (test #"\1\377" integer->integer-bytes -255 2 #t #f)
  (test #"\1\2" integer->integer-bytes 258 2 #f #t)

  (test #"\0\0\0\0" integer->integer-bytes 0 4 #t)
  (test #"\377\377\377\377" integer->integer-bytes -1 4 #t)
  (test #"\377\377\377\377" integer->integer-bytes 4294967295 4 #f)
  ;;
  (test #"\0\0\0\0" integer->integer-bytes 0 4 #t #t)
  (test #"\377\377\377\377" integer->integer-bytes -1 4 #t #t)
  (test #"\377\377\377\377" integer->integer-bytes 4294967295 4 #f #t)
  (test #"\377\0\0\0" integer->integer-bytes -16777216 4 #t #t)
  (test #"\0\0\0\377" integer->integer-bytes 255 4 #t #t)
  ;;
  (test #"\0\0\0\0" integer->integer-bytes 0 4 #t #f)
  (test #"\377\377\377\377" integer->integer-bytes -1 4 #t #f)
  (test #"\377\377\377\377" integer->integer-bytes 4294967295 4 #f #f)
  (test #"\377\0\0\1" integer->integer-bytes 16777471 4 #t #f)
  (test #"\0\0\0\377" integer->integer-bytes -16777216 4 #t #f)
  (test #"\1\0\0\377" integer->integer-bytes -16777215 4 #t #f)

  (test #"matt" integer->integer-bytes 1835103348 4 #t #t)
  (test #"matt" integer->integer-bytes 1953784173 4 #t #f)

  (test #"\0\0\0\0\0\0\0\0" integer->integer-bytes 0 8 #t #t)
  (test #"\377\377\377\377\377\377\377\377" integer->integer-bytes -1 8 #t #f)
  (test #"\377\377\377\377\377\377\377\377" integer->integer-bytes 18446744073709551615 8 #f #f)
  (test #"\377\377\377\377\0\0\0\0" integer->integer-bytes 4294967295 8 #t #f)
  (test #"\0\0\0\0\377\377\377\377" integer->integer-bytes -4294967296 8 #t #f)
  (test #"\377\377\377\377\1\0\0\0" integer->integer-bytes 8589934591 8 #t #f)
  (test #"\1\0\0\0\377\377\377\377" integer->integer-bytes -4294967295 8 #t #f)
  ;;
  (test #"\0\0\0\0\0\0\0\0" integer->integer-bytes 0 8 #t #f)
  (test #"\377\377\377\377\377\377\377\377" integer->integer-bytes -1 8 #t #f)
  (test #"\377\377\377\377\377\377\377\377" integer->integer-bytes 18446744073709551615 8 #f #f)
  (test #"\377\377\377\377\0\0\0\0" integer->integer-bytes -4294967296 8 #t #t)
  (test #"\0\0\0\0\377\377\377\377" integer->integer-bytes 4294967295 8 #t #t)
  (test #"\377\377\377\377\0\0\0\1" integer->integer-bytes -4294967295 8 #t #t)
  (test #"\0\0\0\1\377\377\377\377" integer->integer-bytes 8589934591 8 #t #t))

(test-integer->integer-bytes integer->integer-bytes)
(test-integer->integer-bytes (lambda (num sz signed? [bigend? (system-big-endian?)])
                               (let ([bstr (make-bytes 11 (char->integer #\x))])
                                 (integer->integer-bytes num sz signed? bigend? bstr 3)
                                 (test #"xxx" subbytes bstr 0 3)
                                 (test (make-bytes (- 11 3 sz) (char->integer #\x)) subbytes bstr (+ 3 sz))
                                 (subbytes bstr 3 (+ 3 sz)))))

(arity-test integer->integer-bytes 3 6)
(err/rt-test (integer->integer-bytes 'ack 2 #t))
(err/rt-test (integer->integer-bytes 10 'ack #t))
(err/rt-test (integer->integer-bytes 10 20 #t))
(err/rt-test (integer->integer-bytes 10 2 #t #t 'ack))
(err/rt-test (integer->integer-bytes 10 2 #t #t #"ack")) ; <-- immutable string
(err/rt-test (integer->integer-bytes 100000 2 #t) exn:application:mismatch?)
(err/rt-test (integer->integer-bytes 65536 2 #f) exn:application:mismatch?)
(err/rt-test (integer->integer-bytes 32768 2 #t) exn:application:mismatch?)
(err/rt-test (integer->integer-bytes -32769 2 #t) exn:application:mismatch?)
(err/rt-test (integer->integer-bytes (expt 2 32) 4 #f) exn:application:mismatch?)
(err/rt-test (integer->integer-bytes (expt 2 31) 4 #t) exn:application:mismatch?)
(err/rt-test (integer->integer-bytes (sub1 (- (expt 2 31))) 4 #t) exn:application:mismatch?)
(err/rt-test (integer->integer-bytes (expt 2 64) 8 #f) exn:application:mismatch?)
(err/rt-test (integer->integer-bytes (expt 2 63) 4 #t) exn:application:mismatch?)
(err/rt-test (integer->integer-bytes (sub1 (- (expt 2 63))) 8 #t) exn:application:mismatch?)
(err/rt-test (integer->integer-bytes 100 4 #t #t (make-bytes 3)) exn:application:mismatch?)
(err/rt-test (integer->integer-bytes 100 2 #t #t (make-bytes 3) 2) exn:application:mismatch?)

(map (lambda (v)
       (let-values ([(n size signed?) (apply values v)])
	 (test n integer-bytes->integer (integer->integer-bytes n size signed? #f) signed? #f)
	 (test n integer-bytes->integer (integer->integer-bytes n size signed? #t) signed? #t)))
     (list
      (list 10 2 #t)

      (list (sub1 (expt 2 16)) 2 #f)
      (list (sub1 (expt 2 15)) 2 #t)
      (list (- (expt 2 15)) 2 #t)

      (list (sub1 (expt 2 32)) 4 #f)
      (list (sub1 (expt 2 31)) 4 #t)
      (list (- (expt 2 31)) 4 #t)

      (list (sub1 (expt 2 64)) 8 #f)
      (list (sub1 (expt 2 63)) 8 #t)
      (list (- (expt 2 63)) 8 #t)))

(let ([s (make-bytes 4)]
      [n (random 10000)])
  (test s integer->integer-bytes n 4 #f #f s)
  (test s integer->integer-bytes n 4 #f #f))
|#


#| dyoo: no support for floating-point-bytes->real
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; Used for comparison after loss of precision in 4-byte conversion
(define (close? a b)
  (or (equal? a b)
      (if (negative? a)
	  (>= (* b 0.999) a (* b 1.001))
	  (<= (* b 0.999) a (* b 1.001)))
      (and (= b +inf.0)
	   (> a 1e38))
      (and (= b -inf.0)
	   (< a -1e38))))

(map (lambda (n)
       (test #t close? n (floating-point-bytes->real (real->floating-point-bytes n 4 #t) #t))
       (test #t close? n (floating-point-bytes->real (real->floating-point-bytes n 4 #f) #f))
       (test n floating-point-bytes->real (real->floating-point-bytes n 8 #t) #t)
       (test n floating-point-bytes->real (real->floating-point-bytes n 8 #f) #f))
     (append
      (list 0.0
	    -0.0
	    +inf.0
	    -inf.0
	    +nan.0
	    1.0
	    0.1
	    1e10)
      (let loop ([n 50])
	(if (zero? n)
	    null
	    (cons (* (if (= 1 (random 2)) 1 -1)
		     (sqrt (/ (random 3000) 3000.0))
		     (expt 2.0 (random 300)))
		  (loop (sub1 n)))))))

(define (there-and-back n)
  (floating-point-bytes->real (real->floating-point-bytes n 8)))

(err/rt-test (there-and-back 1.0+0.0i))
(err/rt-test (there-and-back 100.0+0.0i))
(test 101.0 there-and-back 101)
(test 1e30 there-and-back 1000000000000000000000000000000)
(test 0.5 there-and-back 1/2)

(let ([s (make-bytes 8)]
      [n (expt (random 100) (- (random 100)))])
  (test s real->floating-point-bytes n 8 #f s)
  (test s real->floating-point-bytes n 8 #f))

(err/rt-test (real->floating-point-bytes 1 -4))
(err/rt-test (real->floating-point-bytes 1 7))
(err/rt-test (real->floating-point-bytes 1 7000000000000000000000000))
(err/rt-test (real->floating-point-bytes 1+2i 8))
(err/rt-test (real->floating-point-bytes 1.0+2.0i 8))
(err/rt-test (real->floating-point-bytes 1.0 8 #f (make-bytes 7)) exn:application:mismatch?)
|#
;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(report-errs)