~ chicken-core (master) /tests/numbers-test-gauche.scm


   1;;
   2;; test numeric system implementation
   3;;
   4;; These tests are from Gauche Scheme (v0.9.1), which can be found at
   5;; http://practical-scheme.net/gauche/index.html
   6;; Some modifications were made to allow it to be used with the "test"
   7;; egg for Chicken
   8;;
   9;;   Copyright (c) 2000-2010  Shiro Kawai  <shiro@acm.org>
  10;;
  11;;  Redistribution and use in source and binary forms, with or without
  12;;  modification, are permitted provided that the following conditions
  13;;  are met:
  14;;
  15;;   1. Redistributions of source code must retain the above copyright
  16;;      notice, this list of conditions and the following disclaimer.
  17;;
  18;;   2. Redistributions in binary form must reproduce the above copyright
  19;;      notice, this list of conditions and the following disclaimer in the
  20;;      documentation and/or other materials provided with the distribution.
  21;;
  22;;   3. Neither the name of the authors nor the names of its contributors
  23;;      may be used to endorse or promote products derived from this
  24;;      software without specific prior written permission.
  25;;
  26;;  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  27;;  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  28;;  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  29;;  A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  30;;  OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  31;;  SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
  32;;  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  33;;  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  34;;  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  35;;  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  36;;  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  37;;
  38
  39(include "test.scm")
  40
  41(define (exp2 pow)
  42  (do ((i 0 (+ i 1))
  43       (m 1 (+ m m)))
  44      ((>= i pow) m)))
  45
  46(define (fermat n)                      ;Fermat's number
  47  (+ (expt 2 (expt 2 n)) 1))
  48
  49;; Gauche compat
  50
  51(import (chicken bitwise) (chicken port) (chicken format) (chicken string) (chicken fixnum))
  52(import (only (scheme base) exact-integer-sqrt))
  53
  54(define (greatest-fixnum) most-positive-fixnum)
  55(define (least-fixnum) most-negative-fixnum)
  56(define (fixnum-width) fixnum-precision)
  57
  58(define ash arithmetic-shift)
  59(define logior bitwise-ior)
  60(define logand bitwise-and)
  61(define lognot bitwise-not)
  62(define (logtest a b) (= (bitwise-and a b) b))
  63
  64(define-syntax let1
  65  (syntax-rules ()
  66    ((_ var val forms ...)
  67     (let ((var val)) forms ...))))
  68
  69(define (integer->digit i r)
  70  (and (< i r)
  71       (if (< i 10)
  72           (integer->char (+ (char->integer #\0) i))
  73           (integer->char (+ (char->integer #\a) (- i 10))))))
  74
  75(define (read-from-string s) (with-input-from-string s read))
  76
  77(define (truncate->exact x) (inexact->exact (truncate x)))
  78(define (round->exact x) (inexact->exact (round x)))
  79(define (floor->exact x) (inexact->exact (floor x)))
  80(define (ceiling->exact x) (inexact->exact (ceiling x)))
  81
  82;; This is probably a bit silly
  83(define (+. . args) (if (null? args) 0.0 (apply + (map exact->inexact args))))
  84(define (-. . args) (apply - (map exact->inexact args)))
  85(define (*. . args) (if (null? args) 1.0 (apply * (map exact->inexact args))))
  86(define (/. . args) (apply / (map exact->inexact args)))
  87
  88(test-begin "Gauche numbers test")
  89
  90;;==================================================================
  91;; Reader/writer
  92;;
  93
  94;;------------------------------------------------------------------
  95(test-begin "integer addition & reader")
  96
  97(define (i-tester x)
  98  (list x (+ x -1 x) (+ x x) (- x) (- (+ x -1 x)) (- 0 x x) (- 0 x x 1)))
  99
 100(test-equal "around 2^28"
 101      (i-tester (exp2 28))
 102      '(268435456 536870911 536870912
 103         -268435456 -536870911 -536870912 -536870913))
 104
 105(test-equal "around 2^31"
 106      (i-tester (exp2 31))
 107       '(2147483648 4294967295 4294967296
 108         -2147483648 -4294967295 -4294967296 -4294967297))
 109
 110(test-equal "around 2^60"
 111       (i-tester (exp2 60))
 112       '(1152921504606846976 2305843009213693951 2305843009213693952
 113         -1152921504606846976 -2305843009213693951 -2305843009213693952
 114         -2305843009213693953))
 115
 116(test-equal "around 2^63"
 117       (i-tester (exp2 63))
 118       '(9223372036854775808 18446744073709551615 18446744073709551616
 119         -9223372036854775808 -18446744073709551615 -18446744073709551616
 120         -18446744073709551617))
 121
 122(test-equal "around 2^127"
 123       (i-tester (exp2 127))
 124       '(170141183460469231731687303715884105728
 125         340282366920938463463374607431768211455
 126         340282366920938463463374607431768211456
 127         -170141183460469231731687303715884105728
 128         -340282366920938463463374607431768211455
 129         -340282366920938463463374607431768211456
 130         -340282366920938463463374607431768211457))
 131
 132;; test for reader's overflow detection code
 133(test-equal "peculiarity around 2^32"
 134      (* 477226729 10) 4772267290)
 135
 136(test-equal "radix" (list #b1010101001010101
 137             #o1234567
 138             #o12345677654321
 139             #d123456789
 140             #d123456789987654321
 141             #x123456
 142             #xdeadbeef
 143             #xDeadBeef)
 144      '(43605 342391 718048024785
 145                 123456789 123456789987654321
 146                 1193046 3735928559 3735928559))
 147
 148(test-equal "exactness" (exact? #e10) #t)
 149(test-equal "exactness" (exact? #e10.0) #t)
 150(test-equal "exactness" (exact? #e10e10) #t)
 151(test-equal "exactness" (exact? #e12.34) #t)
 152(test-equal "inexactness" (exact? #i10) #f)
 153(test-equal "inexactness" (exact? #i10.0) #f)
 154(test-equal "inexactness" (exact? #i12.34) #f)
 155
 156(test-equal "exactness & radix" (list (exact? #e#xdeadbeef)
 157             #e#xdeadbeef
 158             (exact? #x#edeadbeef)
 159             #x#edeadbeef)
 160      '(#t 3735928559 #t 3735928559))
 161(test-equal "inexactness & radix" (list (exact? #i#xdeadbeef)
 162             #i#xdeadbeef
 163             (exact? #x#ideadbeef)
 164             #x#ideadbeef)
 165      '(#f 3735928559.0 #f 3735928559.0))
 166
 167(test-equal "invalid exactness/radix spec" (or (string->number "#e")
 168           (string->number "#i")
 169           (string->number "#e#i3")
 170           (string->number "#i#e5")
 171           (string->number "#x#o13")
 172           (string->number "#e#b#i00101"))
 173       #f)
 174
 175(define (radix-tester radix)
 176  (list
 177   (let loop ((digits 0)
 178              (input "1")
 179              (value 1))
 180     (cond ((> digits 64) #t)
 181           ((eqv? (string->number input radix) value)
 182            (loop (+ digits 1) (string-append input "0") (* value radix)))
 183           (else #f)))
 184   (let loop ((digits 0)
 185              (input (string (integer->digit (- radix 1) radix)))
 186              (value (- radix 1)))
 187     (cond ((> digits 64) #t)
 188           ((eqv? (string->number input radix) value)
 189            (loop (+ digits 1)
 190                  (string-append input (string (integer->digit (- radix 1) radix)))
 191                  (+ (* value radix) (- radix 1))))
 192           (else #f)))))
 193
 194(test-equal "base-2 reader" (radix-tester 2) '(#t #t))
 195(test-equal "base-3 reader" (radix-tester 3) '(#t #t))
 196(test-equal "base-4 reader" (radix-tester 4) '(#t #t))
 197(test-equal "base-5 reader" (radix-tester 5) '(#t #t))
 198(test-equal "base-6 reader" (radix-tester 6) '(#t #t))
 199(test-equal "base-7 reader" (radix-tester 7) '(#t #t))
 200(test-equal "base-8 reader" (radix-tester 8) '(#t #t))
 201(test-equal "base-9 reader" (radix-tester 9) '(#t #t))
 202(test-equal "base-10 reader" (radix-tester 10) '(#t #t))
 203(test-equal "base-11 reader" (radix-tester 11) '(#t #t))
 204(test-equal "base-12 reader" (radix-tester 12) '(#t #t))
 205(test-equal "base-13 reader" (radix-tester 13) '(#t #t))
 206(test-equal "base-14 reader" (radix-tester 14) '(#t #t))
 207(test-equal "base-15 reader" (radix-tester 15) '(#t #t))
 208(test-equal "base-16 reader" (radix-tester 16) '(#t #t))
 209(test-equal "base-17 reader" (radix-tester 17) '(#t #t))
 210(test-equal "base-18 reader" (radix-tester 18) '(#t #t))
 211(test-equal "base-19 reader" (radix-tester 19) '(#t #t))
 212(test-equal "base-20 reader" (radix-tester 20) '(#t #t))
 213(test-equal "base-21 reader" (radix-tester 21) '(#t #t))
 214(test-equal "base-22 reader" (radix-tester 22) '(#t #t))
 215(test-equal "base-23 reader" (radix-tester 23) '(#t #t))
 216(test-equal "base-24 reader" (radix-tester 24) '(#t #t))
 217(test-equal "base-25 reader" (radix-tester 25) '(#t #t))
 218(test-equal "base-26 reader" (radix-tester 26) '(#t #t))
 219(test-equal "base-27 reader" (radix-tester 27) '(#t #t))
 220(test-equal "base-28 reader" (radix-tester 28) '(#t #t))
 221(test-equal "base-29 reader" (radix-tester 29) '(#t #t))
 222(test-equal "base-30 reader" (radix-tester 30) '(#t #t))
 223(test-equal "base-31 reader" (radix-tester 31) '(#t #t))
 224(test-equal "base-32 reader" (radix-tester 32) '(#t #t))
 225(test-equal "base-33 reader" (radix-tester 33) '(#t #t))
 226(test-equal "base-34 reader" (radix-tester 34) '(#t #t))
 227(test-equal "base-35 reader" (radix-tester 35) '(#t #t))
 228(test-equal "base-36 reader" (radix-tester 36) '(#t #t))
 229
 230(test-end)
 231
 232;;------------------------------------------------------------------
 233(test-begin "rational reader")
 234
 235(define (rational-test v)
 236  (if (number? v) (list v (exact? v)) v))
 237
 238(test-equal "rational reader" (rational-test '1234/1) '(1234 #t))
 239(test-equal "rational reader" (rational-test '-1234/1) '(-1234 #t))
 240(test-equal "rational reader" (rational-test '+1234/1) '(1234 #t))
 241;; The following is invalid R5RS syntax, so it's commented out (it fails, too)
 242#;(test-equal "rational reader" (rational-test '1234/-1) '|1234/-1|)
 243(test-equal "rational reader" (rational-test '2468/2) '(1234 #t))
 244(test-equal "rational reader" (rational-test '1/2) '(1/2 #t))
 245(test-equal "rational reader" (rational-test '-1/2) '(-1/2 #t))
 246(test-equal "rational reader" (rational-test '+1/2) '(1/2 #t))
 247(test-equal "rational reader" (rational-test '751/1502) '(1/2 #t))
 248
 249(test-equal "rational reader" (rational-test (string->number "3/03"))
 250       '(1 #t))
 251(test-equal "rational reader" (rational-test (string->number "3/0")) #;'(+inf.0 #f) ; <- I think that's wrong in Gauche
 252       #f)
 253(test-equal "rational reader" (rational-test (string->number "-3/0")) #;'(-inf.0 #f) ; same as above
 254       #f)
 255(test-equal "rational reader" (rational-test (string->number "3/3/4"))
 256       #f)
 257(test-equal "rational reader" (rational-test (string->number "1/2."))
 258       #f)
 259(test-equal "rational reader" (rational-test (string->number "1.3/2"))
 260       #f)
 261
 262(test-error "rational reader" (rational-test (read-from-string "#e3/0")))
 263(test-error "rational reader" (rational-test (read-from-string "#e-3/0")))
 264
 265(test-equal "rational reader w/#e" (rational-test '#e1234/1)
 266       '(1234 #t))
 267(test-equal "rational reader w/#e" (rational-test '#e-1234/1)
 268       '(-1234 #t))
 269(test-equal "rational reader w/#e" (rational-test '#e32/7)
 270       '(32/7 #t))
 271(test-equal "rational reader w/#e" (rational-test '#e-32/7)
 272       '(-32/7 #t))
 273(test-equal "rational reader w/#i" (rational-test '#i1234/1)
 274       '(1234.0 #f))
 275(test-equal "rational reader w/#i" (rational-test '#i-1234/1)
 276       '(-1234.0 #f))
 277(test-equal "rational reader w/#i" (rational-test '#i-4/32)
 278       '(-0.125 #f))
 279
 280(test-equal "rational reader w/radix" (rational-test '#e#xff/11)
 281       '(15 #t))
 282(test-equal "rational reader w/radix" (rational-test '#o770/11)
 283       '(56 #t))
 284(test-equal "rational reader w/radix" (rational-test '#x#iff/11)
 285       '(15.0 #f))
 286
 287(test-equal "rational reader edge case" (symbol? (read-from-string "/1")) #t)
 288(test-equal "rational reader edge case" (symbol? (read-from-string "-/1")) #t)
 289(test-equal "rational reader edge case" (symbol? (read-from-string "+/1")) #t)
 290
 291(test-end)
 292
 293;;------------------------------------------------------------------
 294(test-begin "flonum reader")
 295
 296(define (flonum-test v)
 297  (if (number? v) (list v (inexact? v)) v))
 298
 299(test-equal "flonum reader" (flonum-test 3.14)  '(3.14 #t))
 300(test-equal "flonum reader" (flonum-test 0.14)  '(0.14 #t))
 301(test-equal "flonum reader" (flonum-test .14)  '(0.14 #t))
 302(test-equal "flonum reader" (flonum-test 3.)  '(3.0  #t))
 303(test-equal "flonum reader" (flonum-test -3.14)  '(-3.14 #t))
 304(test-equal "flonum reader" (flonum-test -0.14)  '(-0.14 #t))
 305(test-equal "flonum reader" (flonum-test -.14)  '(-0.14 #t))
 306(test-equal "flonum reader" (flonum-test -3.)  '(-3.0  #t))
 307(test-equal "flonum reader" (flonum-test +3.14)  '(3.14 #t))
 308(test-equal "flonum reader" (flonum-test +0.14)  '(0.14 #t))
 309(test-equal "flonum reader" (flonum-test +.14)  '(0.14 #t))
 310(test-equal "flonum reader" (flonum-test +3.)  '(3.0  #t))
 311(test-equal "flonum reader" (flonum-test .0)  '(0.0  #t))
 312(test-equal "flonum reader" (flonum-test 0.)  '(0.0  #t))
 313(test-equal "flonum reader" (string->number ".") #f)
 314(test-equal "flonum reader" (string->number "-.") #f)
 315(test-equal "flonum reader" (string->number "+.") #f)
 316
 317(test-equal "flonum reader (exp)" (flonum-test 3.14e2) '(314.0 #t))
 318(test-equal "flonum reader (exp)" (flonum-test .314e3) '(314.0 #t))
 319(test-equal "flonum reader (exp)" (flonum-test 314e0) '(314.0 #t))
 320(test-equal "flonum reader (exp)" (flonum-test 314e-0) '(314.0 #t))
 321(test-equal "flonum reader (exp)" (flonum-test 3140000e-4) '(314.0 #t))
 322(test-equal "flonum reader (exp)" (flonum-test -3.14e2) '(-314.0 #t))
 323(test-equal "flonum reader (exp)" (flonum-test -.314e3) '(-314.0 #t))
 324(test-equal "flonum reader (exp)" (flonum-test -314e0) '(-314.0 #t))
 325(test-equal "flonum reader (exp)" (flonum-test -314.e-0) '(-314.0 #t))
 326(test-equal "flonum reader (exp)" (flonum-test -3140000e-4) '(-314.0 #t))
 327(test-equal "flonum reader (exp)" (flonum-test +3.14e2) '(314.0 #t))
 328(test-equal "flonum reader (exp)" (flonum-test +.314e3) '(314.0 #t))
 329(test-equal "flonum reader (exp)" (flonum-test +314.e0) '(314.0 #t))
 330(test-equal "flonum reader (exp)" (flonum-test +314e-0) '(314.0 #t))
 331(test-equal "flonum reader (exp)" (flonum-test +3140000.000e-4) '(314.0 #t))
 332
 333(test-equal "flonum reader (exp)" (flonum-test .314E3) '(314.0 #t))
 334(test-equal "flonum reader (exp)" (flonum-test .314s3) '(314.0 #t))
 335(test-equal "flonum reader (exp)" (flonum-test .314S3) '(314.0 #t))
 336(test-equal "flonum reader (exp)" (flonum-test .314l3) '(314.0 #t))
 337(test-equal "flonum reader (exp)" (flonum-test .314L3) '(314.0 #t))
 338(test-equal "flonum reader (exp)" (flonum-test .314f3) '(314.0 #t))
 339(test-equal "flonum reader (exp)" (flonum-test .314F3) '(314.0 #t))
 340(test-equal "flonum reader (exp)" (flonum-test .314d3) '(314.0 #t))
 341(test-equal "flonum reader (exp)" (flonum-test .314D3) '(314.0 #t))
 342
 343;; Broken for unknown reasons on Mingw
 344#;(test-equal "flonum reader (minimum denormalized number 5.0e-324)" (let1 x (expt 2.0 -1074)
 345         (= x (string->number (number->string x))))
 346       #t)
 347#;(test-equal "flonum reader (minimum denormalized number -5.0e-324)" (let1 x (- (expt 2.0 -1074))
 348         (= x (string->number (number->string x))))
 349       #t)
 350       
 351
 352(test-equal "padding" (flonum-test '1#) '(10.0 #t))
 353(test-equal "padding" (flonum-test '1#.) '(10.0 #t))
 354(test-equal "padding" (flonum-test '1#.#) '(10.0 #t))
 355(test-equal "padding" (flonum-test '10#.#) '(100.0 #t))
 356(test-equal "padding" (flonum-test '1##.#) '(100.0 #t))
 357(test-equal "padding" (flonum-test '100.0#) '(100.0 #t))
 358(test-equal "padding" (flonum-test '1.#) '(1.0 #t))
 359
 360(test-equal "padding" (flonum-test '1#1) '|1#1|)
 361(test-equal "padding" (flonum-test '1##1) '|1##1|)
 362(test-equal "padding" (flonum-test '1#.1) '|1#.1|)
 363(test-equal "padding" (flonum-test '1.#1) '|1.#1|)
 364
 365(test-equal "padding" (flonum-test '.#) '|.#|)
 366(test-equal "padding" (flonum-test '0.#) '(0.0 #t))
 367(test-equal "padding" (flonum-test '.0#) '(0.0 #t))
 368(test-equal "padding" (flonum-test '0#) '(0.0 #t))
 369(test-equal "padding" (flonum-test '0#.#) '(0.0 #t))
 370(test-equal "padding" (flonum-test '0#.0) '|0#.0|)
 371
 372(test-equal "padding" (flonum-test '1#e2) '(1000.0 #t))
 373(test-equal "padding" (flonum-test '1##e1) '(1000.0 #t))
 374(test-equal "padding" (flonum-test '1#.##e2) '(1000.0 #t))
 375(test-equal "padding" (flonum-test '0.#e2) '(0.0 #t))
 376(test-equal "padding" (flonum-test '.0#e2) '(0.0 #t))
 377(test-equal "padding" (flonum-test '.##e2) '|.##e2|)
 378
 379(test-equal "padding (exactness)" (flonum-test '#e1##) '(100 #f))
 380(test-equal "padding (exactness)" (flonum-test '#e12#) '(120 #f))
 381(test-equal "padding (exactness)" (flonum-test '#e12#.#) '(120 #f))
 382(test-equal "padding (exactness)" (flonum-test '#i1##) '(100.0 #t))
 383(test-equal "padding (exactness)" (flonum-test '#i12#) '(120.0 #t))
 384(test-equal "padding (exactness)" (flonum-test '#i12#.#) '(120.0 #t))
 385
 386(test-equal "exponent out-of-range 1" (flonum-test '1e309) '(+inf.0 #t))
 387(test-equal "exponent out-of-range 2" (flonum-test '1e10000) '(+inf.0 #t))
 388;; TODO: Figure out what goes wrong here
 389;(test-equal "exponent out-of-range 3" (flonum-test '1e1000000000000000000000000000000000000000000000000000000000000000) '(+inf.0 #t))
 390(test-equal "exponent out-of-range 4" (flonum-test '-1e309) '(-inf.0 #t))
 391(test-equal "exponent out-of-range 5" (flonum-test '-1e10000) '(-inf.0 #t))
 392;(test-equal "exponent out-of-range 6" (flonum-test '-1e1000000000000000000000000000000000000000000000000000000000000000) '(-inf.0 #t))
 393(test-equal "exponent out-of-range 7" (flonum-test '1e-324) '(0.0 #t))
 394(test-equal "exponent out-of-range 8" (flonum-test '1e-1000) '(0.0 #t))
 395;(test-equal "exponent out-of-range 9" (flonum-test '1e-1000000000000000000000000000000000000000000000000000000000000000000) '(0.0 #t))
 396
 397(test-equal "no integral part" (read-from-string ".5") 0.5)
 398(test-equal "no integral part" (read-from-string "-.5") -0.5)
 399(test-equal "no integral part" (read-from-string "+.5") 0.5)
 400(test-end)
 401
 402;;------------------------------------------------------------------
 403(test-begin "exact fractional number")
 404
 405(test-equal "exact fractonal number" (string->number "#e1.2345e4")
 406       12345)
 407(test-equal "exact fractonal number" (string->number "#e1.2345e14")
 408       123450000000000)
 409(test-equal "exact fractonal number" (string->number "#e1.2345e2")
 410       12345/100)
 411(test-equal "exact fractonal number" (string->number "#e1.2345e-2")
 412       12345/1000000)
 413(test-equal "exact fractonal number" (string->number "#e-1.2345e4")
 414       -12345)
 415(test-equal "exact fractonal number" (string->number "#e-1.2345e14")
 416       -123450000000000)
 417(test-equal "exact fractonal number" (string->number "#e-1.2345e2")
 418       -12345/100)
 419(test-equal "exact fractonal number" (string->number "#e-1.2345e-2")
 420       -12345/1000000)
 421
 422(test-equal "exact fractonal number" (string->number "#e0.0001e300")
 423       (expt 10 296))
 424(test-equal "exact fractonal number" (string->number "#e-0.0001e300")
 425       (- (expt 10 296)))
 426
 427(test-equal "exact fractonal number" (read-from-string "#e1e330")
 428      (expt 10 330))
 429(test-equal "exact fractonal number" (read-from-string "#e1e-330")
 430      (expt 10 -330))
 431
 432(test-end)
 433
 434;;------------------------------------------------------------------
 435(test-begin "complex reader")
 436
 437(define (decompose-complex z)
 438  (cond ((real? z) z)
 439        ((complex? z)
 440         (list (real-part z) (imag-part z)))
 441        (else z)))
 442
 443;; Fixed for exactness (Gauche's complex numbers are always inexact)
 444(test-equal "complex reader" (decompose-complex '1+i) '(1 1))
 445(test-equal "complex reader" (decompose-complex '1+1i) '(1 1))
 446(test-equal "complex reader" (decompose-complex '1-i) '(1 -1))
 447(test-equal "complex reader" (decompose-complex '1-1i) '(1 -1))
 448(test-equal "complex reader" (decompose-complex '1.0+1i) '(1.0 1.0))
 449(test-equal "complex reader" (decompose-complex '1.0+1.0i) '(1.0 1.0))
 450(test-equal "complex reader" (decompose-complex '1e-5+1i) '(1e-5 1.0))
 451(test-equal "complex reader" (decompose-complex '1e+5+1i) '(1e+5 1.0))
 452(test-equal "complex reader" (decompose-complex '1+1e-5i) '(1.0 1e-5))
 453(test-equal "complex reader" (decompose-complex '1+1e+5i) '(1.0 1e+5))
 454(test-equal "complex reader" (decompose-complex '0.1+0.1e+5i) '(0.1 1e+4))
 455(test-equal "complex reader" (decompose-complex '+i) '(0 1))
 456(test-equal "complex reader" (decompose-complex '-i) '(0 -1))
 457(test-equal "complex reader" (decompose-complex '+1i) '(0 1))
 458(test-equal "complex reader" (decompose-complex '-1i) '(0 -1))
 459(test-equal "complex reader" (decompose-complex '+1.i) '(0.0 1.0))
 460(test-equal "complex reader" (decompose-complex '-1.i) '(0.0 -1.0))
 461(test-equal "complex reader" (decompose-complex '+1.0i) '(0.0 1.0))
 462(test-equal "complex reader" (decompose-complex '-1.0i) '(0.0 -1.0))
 463(test-equal "complex reader" (decompose-complex '1+0.0i) 1.0)
 464(test-equal "complex reader" (decompose-complex '1+.0i) 1.0)
 465(test-equal "complex reader" (decompose-complex '1+0.i) 1.0)
 466(test-equal "complex reader" (decompose-complex '1+0.0e-43i) 1.0)
 467(test-equal "complex reader" (decompose-complex '1e2+0.0e-43i) 100.0)
 468
 469(test-equal "complex reader" (decompose-complex 'i) 'i)
 470(test-equal "complex reader" (decompose-complex (string->number ".i")) #f)
 471(test-equal "complex reader" (decompose-complex (string->number "+.i")) #f)
 472(test-equal "complex reader" (decompose-complex (string->number "-.i")) #f)
 473(test-equal "complex reader" (decompose-complex '33i) '33i)
 474(test-equal "complex reader" (decompose-complex 'i+1) 'i+1)
 475(test-equal "complex reader" (decompose-complex '++i) '|++i|)
 476(test-equal "complex reader" (decompose-complex '--i) '|--i|)
 477
 478(test-equal "complex reader" (decompose-complex 1/2+1/2i) '(1/2 1/2))
 479(test-equal "complex reader" (decompose-complex 0+1/2i) '(0 1/2))
 480(test-equal "complex reader" (decompose-complex -1/2i) '(0 -1/2))
 481(test-equal "complex reader" (decompose-complex 1/2-0/2i) 1/2)
 482;; The following is also invalid R5RS syntax, so it's commented out
 483#;(test-equal "complex reader" (decompose-complex (string->number "1/2-1/0i")) '(0.5 -inf.0))
 484
 485(test-equal "complex reader (polar)" (make-polar 1.0 1.0) 1.0@1.0)
 486(test-equal "complex reader (polar)" (make-polar 1.0 -1.0) 1.0@-1.0)
 487(test-equal "complex reader (polar)" (make-polar 1.0 1.0) 1.0@+1.0)
 488(test-equal "complex reader (polar)" (make-polar -7.0 -3.0) -7@-3.0)
 489(test-equal "complex reader (polar)" (make-polar 3.5 -3.0) 7/2@-3.0)
 490(test-equal "complex reader (polar)" (string->number "7/2@-3.14i") #f)
 491
 492(test-end)
 493
 494;;------------------------------------------------------------------
 495(test-begin "integer writer syntax")
 496
 497(define (i-tester2 x)
 498  (map number->string (i-tester x)))
 499
 500(test-equal "around 2^28"
 501      (i-tester2 (exp2 28))
 502      '("268435456" "536870911" "536870912"
 503        "-268435456" "-536870911" "-536870912" "-536870913"))
 504      
 505(test-equal "around 2^31"
 506      (i-tester2 (exp2 31))
 507      '("2147483648" "4294967295" "4294967296"
 508        "-2147483648" "-4294967295" "-4294967296" "-4294967297"))
 509
 510(test-equal "around 2^60"
 511      (i-tester2 (exp2 60))
 512      '("1152921504606846976" "2305843009213693951" "2305843009213693952"
 513        "-1152921504606846976" "-2305843009213693951" "-2305843009213693952"
 514        "-2305843009213693953"))
 515
 516(test-equal "around 2^63"
 517      (i-tester2 (exp2 63))
 518      '("9223372036854775808" "18446744073709551615" "18446744073709551616"
 519        "-9223372036854775808" "-18446744073709551615" "-18446744073709551616"
 520        "-18446744073709551617"))
 521
 522(test-equal "around 2^127"
 523      (i-tester2 (exp2 127))
 524      '("170141183460469231731687303715884105728"
 525        "340282366920938463463374607431768211455"
 526        "340282366920938463463374607431768211456"
 527        "-170141183460469231731687303715884105728"
 528        "-340282366920938463463374607431768211455"
 529        "-340282366920938463463374607431768211456"
 530        "-340282366920938463463374607431768211457"))
 531
 532(test-end)
 533
 534;;==================================================================
 535;; Conversions
 536;;
 537
 538;; We first test expt, for we need to use it to test exact<->inexact
 539;; conversion stuff.
 540(test-begin "expt")
 541
 542(test-equal "exact expt" (expt 5 0) 1)
 543(test-equal "exact expt" (expt 5 10) 9765625)
 544(test-equal "exact expt" (expt 5 13) 1220703125)
 545(test-equal "exact expt" (expt 5 123) 94039548065783000637498922977779654225493244541767001720700136502273380756378173828125)
 546(test-equal "exact expt" (expt 5 -123) 1/94039548065783000637498922977779654225493244541767001720700136502273380756378173828125)
 547(test-equal "exact expt" (expt -5 0) 1)
 548(test-equal "exact expt" (expt -5 10) 9765625)
 549(test-equal "exact expt" (expt -5 13) -1220703125)
 550(test-equal "exact expt" (expt -5 123) -94039548065783000637498922977779654225493244541767001720700136502273380756378173828125)
 551(test-equal "exact expt" (expt -5 -123) -1/94039548065783000637498922977779654225493244541767001720700136502273380756378173828125)
 552(test-equal "exact expt" (expt 1 720000) 1)
 553(test-equal "exact expt" (expt -1 720000) 1)
 554(test-equal "exact expt" (expt -1 720001) -1)
 555
 556(test-equal "exact expt (ratinoal)" (expt 2/3 33)
 557       8589934592/5559060566555523)
 558(test-equal "exact expt (rational)" (expt -2/3 33)
 559       -8589934592/5559060566555523)
 560(test-equal "exact expt (ratinoal)" (expt 2/3 -33)
 561       5559060566555523/8589934592)
 562
 563(test-end)
 564
 565(parameterize ((current-test-epsilon 10e7))
 566  (test-equal "expt (coercion to inexact)" (expt 2 1/2)
 567        1.4142135623730951)) ;; NB: pa$ will be tested later
 568
 569(test-begin "exact<->inexact")
 570
 571(for-each
 572 (lambda (e&i)
 573   (let ((e (car e&i))
 574         (i (cdr e&i)))
 575     (test-equal (format "exact->inexact ~s" i) (exact->inexact e) i)
 576     (test-equal (format "exact->inexact ~s" (- i)) (exact->inexact (- e)) (- i))
 577     (test-equal (format "inexact->exact ~s" e) (inexact->exact i) e)
 578     (test-equal (format "inexact->exact ~s" (- e)) (inexact->exact (- i)) (- e))
 579     ))
 580 `((0  . 0.0)
 581   (1  . 1.0)
 582   (-1 . -1.0)
 583   (,(expt 2 52) . ,(expt 2.0 52))
 584   (,(expt 2 53) . ,(expt 2.0 53))
 585   (,(expt 2 54) . ,(expt 2.0 54))
 586   ))
 587
 588;; Rounding bignum to flonum, edge cases.
 589;; Test patterns:
 590;;
 591;;   <------53bits------->
 592;;a) 100000000...000000000100000....0000       round down (r0)
 593;;b) 100000000...000000000100000....0001       round up (r1)
 594;;c) 100000000...000000001100000....0000       round up (r2)
 595;;d) 100000000...000000001011111....1111       round down (r1)
 596;;e) 111111111...111111111100000....0000       round up, carry over (* r0 2)
 597;;f) 101111111...111111111100000....0000       round up, no carry over (r3)
 598;;            <--32bits-->
 599;;g) 100..0000111.....1111100000....0000       round up; boundary on ILP32 (r4)
 600
 601(let loop ((n 0)
 602           (a (+ (expt 2 53) 1))
 603           (c (+ (expt 2 53) 3))
 604           (e (- (expt 2 54) 1))
 605           (f (+ (expt 2 53) (expt 2 52) -1))
 606           (g (+ (expt 2 53) (expt 2 33) -1))
 607           (r0 (expt 2.0 53))
 608           (r1 (+ (expt 2.0 53) 2.0))
 609           (r2 (+ (expt 2.0 53) 4.0))
 610           (r3 (+ (expt 2.0 53) (expt 2.0 52)))
 611           (r4 (+ (expt 2.0 53) (expt 2.0 33))))
 612  (when (< n 32)
 613    (test-equal (format "exact->inexact, pattern a: round down (~a)" n)
 614           (exact->inexact a) r0)
 615    (test-equal (format "exact->inexact, pattern b: round up   (~a)" n)
 616           (exact->inexact (+ a 1)) r1)
 617    (test-equal (format "exact->inexact, pattern c: round up   (~a)" n)
 618           (exact->inexact c) r2)
 619    (test-equal (format "exact->inexact, pattern d: round down (~a)" n)
 620           (exact->inexact (- c 1)) r1)
 621    (test-equal (format "exact->inexact, pattern e: round up   (~a)" n)
 622           (exact->inexact e) (* r0 2.0))
 623    (test-equal (format "exact->inexact, pattern f: round up   (~a)" n)
 624           (exact->inexact f) r3)
 625    (test-equal (format "exact->inexact, pattern g: round up   (~a)" n)
 626           (exact->inexact g) r4)
 627    (loop (+ n 1) (ash a 1) (ash c 1) (ash e 1) (ash f 1) (ash g 1)
 628          (* r0 2.0) (* r1 2.0) (* r2 2.0) (* r3 2.0) (* r4 2.0))))
 629
 630
 631(parameterize ((current-test-epsilon 10e12))
 632  (test-equal "expt (ratnum with large denom and numer) with inexact conversion 1"
 633        (exact->inexact (expt 8/9 342))
 634        (expt 8/9 342.0))
 635
 636  (test-equal "expt (ratnum with large denom and numer) with inexact conversion 2"
 637        (exact->inexact (expt -8/9 343))
 638        (expt -8/9 343.0)))
 639
 640;; The following few tests covers RATNUM paths in Scm_GetDouble
 641(test-equal "expt (ratnum with large denom and numer) with inexact conversion 3"
 642       (exact->inexact (/ (expt 10 20) (expt 10 328))) 1.0e-308)
 643;; In the original Gauche test this checked for a return value of 0.0, but
 644;; that's quite Gauche-specific.  We return 1.0e-309.
 645;; It's probably wrong to test this kind of behaviour in the first place...
 646(test-equal "expt (ratnum with large denom and numer) with inexact conversion 4"
 647       (exact->inexact (/ (expt 10 20) (expt 10 329))) 1.0e-309)
 648(test-equal "expt (ratnum with large denom and numer) with inexact conversion 5"
 649       (exact->inexact (/ (expt 10 328) (expt 10 20))) 1.0e308)
 650(test-equal "expt (ratnum with large denom and numer) with inexact conversion 6"
 651       (exact->inexact (/ (expt 10 329) (expt 10 20))) +inf.0)
 652(test-equal "expt (ratnum with large denom and numer) with inexact conversion 7"
 653       (exact->inexact (/ (expt -10 329) (expt 10 20))) -inf.0)
 654
 655(test-end)
 656
 657;;==================================================================
 658;; Predicates
 659;;
 660
 661(test-begin "predicates")
 662
 663(test-equal "integer?" (integer? 0) #t)
 664(test-equal "integer?" (integer? 85736847562938475634534245) #t)
 665(test-equal "integer?" (integer? 85736.534245) #f)
 666(test-equal "integer?" (integer? 3.14) #f)
 667(test-equal "integer?" (integer? 3+4i) #f)
 668(test-equal "integer?" (integer? 3+0i) #t)
 669(test-equal "integer?" (integer? #f) #f)
 670
 671(test-equal "rational?" (rational? 0) #t)
 672(test-equal "rational?" (rational? 85736847562938475634534245) #t)
 673(test-equal "rational?" (rational? 1/2) #t)
 674(test-equal "rational?" (rational? 85736.534245) #t)
 675(test-equal "rational?" (rational? 3.14) #t)
 676(test-equal "rational?" (rational? 3+4i) #f)
 677(test-equal "rational?" (rational? 3+0i) #t)
 678(test-equal "rational?" (rational? #f) #f)
 679(test-equal "rational?" (rational? +inf.0) #f)
 680(test-equal "rational?" (rational? -inf.0) #f)
 681(test-equal "rational?" (rational? +nan.0) #f)
 682
 683(test-equal "real?" (real? 0) #t)
 684(test-equal "real?" (real? 85736847562938475634534245) #t)
 685(test-equal "real?" (real? 857368.4756293847) #t)
 686(test-equal "real?" (real? 3+0i) #t)
 687(test-equal "real?" (real? 3+4i) #f)
 688(test-equal "real?" (real? +4.3i) #f)
 689(test-equal "real?" (real? '()) #f)
 690(test-equal "real?" (real? +inf.0) #t)
 691(test-equal "real?" (real? -inf.0) #t)
 692(test-equal "real?" (real? +nan.0) #t)
 693
 694(test-equal "complex?" (complex? 0) #t)
 695(test-equal "complex?" (complex? 85736847562938475634534245) #t)
 696(test-equal "complex?" (complex? 857368.4756293847) #t)
 697(test-equal "complex?" (complex? 3+0i) #t)
 698(test-equal "complex?" (complex? 3+4i) #t)
 699(test-equal "complex?" (complex? +4.3i) #t)
 700(test-equal "complex?" (complex? '()) #f)
 701
 702(test-equal "number?" (number? 0) #t)
 703(test-equal "number?" (number? 85736847562938475634534245) #t)
 704(test-equal "number?" (number? 857368.4756293847) #t)
 705(test-equal "number?" (number? 3+0i) #t)
 706(test-equal "number?" (number? 3+4i) #t)
 707(test-equal "number?" (number? +4.3i) #t)
 708(test-equal "number?" (number? '()) #f)
 709
 710(test-equal "exact?" (exact? 1) #t)
 711(test-equal "exact?" (exact? 4304953480349304983049304953804) #t)
 712(test-equal "exact?" (exact? 430495348034930/4983049304953804) #t)
 713(test-equal "exact?" (exact? 1.0) #f)
 714(test-equal "exact?" (exact? 4304953480349304983.049304953804) #f)
 715(test-equal "exact?" (exact? 1.0+0i) #f)
 716(test-equal "exact?" (exact? 1.0+5i) #f)
 717(test-equal "inexact?" (inexact? 1) #f)
 718(test-equal "inexact?" (inexact? 4304953480349304983049304953804) #f)
 719(test-equal "inexact?" (inexact? 430495348034930/4983049304953804) #f)
 720(test-equal "inexact?" (inexact? 1.0) #t)
 721(test-equal "inexact?" (inexact? 4304953480349304983.049304953804) #t)
 722(test-equal "inexact?" (inexact? 1.0+0i) #t)
 723(test-equal "inexact?" (inexact? 1.0+5i) #t)
 724
 725(test-equal "odd?" (odd? 1) #t)
 726(test-equal "odd?" (odd? 2) #f)
 727(test-equal "even?" (even? 1) #f)
 728(test-equal "even?" (even? 2) #t)
 729(test-equal "odd?" (odd? 1.0) #t)
 730(test-equal "odd?" (odd? 2.0) #f)
 731(test-equal "even?" (even? 1.0) #f)
 732(test-equal "even?" (even? 2.0) #t)
 733(test-equal "odd?" (odd? 10000000000000000000000000000000000001) #t)
 734(test-equal "odd?" (odd? 10000000000000000000000000000000000002) #f)
 735(test-equal "even?" (even? 10000000000000000000000000000000000001) #f)
 736(test-equal "even?" (even? 10000000000000000000000000000000000002) #t)
 737
 738(test-equal "zero?" (zero? 0) #t)
 739(test-equal "zero?" (zero? 0.0) #t)
 740(test-equal "zero?" (zero? (- 10 10.0)) #t)
 741(test-equal "zero?" (zero? 0+0i) #t)
 742(test-equal "zero?" (zero? 1.0) #f)
 743(test-equal "zero?" (zero? +5i) #f)
 744(test-equal "positive?" (positive? 1) #t)
 745(test-equal "positive?" (positive? -1) #f)
 746(test-equal "positive?" (positive? 1/7) #t)
 747(test-equal "positive?" (positive? -1/7) #f)
 748(test-equal "positive?" (positive? 3.1416) #t)
 749(test-equal "positive?" (positive? -3.1416) #f)
 750(test-equal "positive?" (positive? 134539485343498539458394) #t)
 751(test-equal "positive?" (positive? -134539485343498539458394) #f)
 752(test-equal "negative?" (negative? 1) #f)
 753(test-equal "negative?" (negative? -1) #t)
 754(test-equal "negative?" (negative? 1/7) #f)
 755(test-equal "negative?" (negative? -1/7) #t)
 756(test-equal "negative?" (negative? 3.1416) #f)
 757(test-equal "negative?" (negative? -3.1416) #t)
 758(test-equal "negative?" (negative? 134539485343498539458394) #f)
 759(test-equal "negative?" (negative? -134539485343498539458394) #t)
 760
 761(let-syntax ((tester (syntax-rules ()
 762                       ((_ name proc result)
 763                        (begin (test-error name (proc #t))
 764                               (test-equal name (list (proc 1)
 765                                                       (proc +inf.0)
 766                                                       (proc -inf.0)
 767                                                       (proc +nan.0)) result))))))
 768  (tester "finite?"   finite?   `(#t #f #f #f))
 769  (tester "infinite?" infinite? `(#f #t #t #f))
 770  (tester "nan?"      nan?      `(#f #f #f #t))
 771  )
 772
 773
 774(test-equal "eqv?" (eqv? 20 20) #t)
 775(test-equal "eqv?" (eqv? 20.0 20.00000) #t)
 776(test-equal "eqv?" (eqv? 4/5 0.8) #f)
 777(test-equal "eqv?" (eqv? (exact->inexact 4/5) 0.8) #t)
 778(test-equal "eqv?" (eqv? 4/5 (inexact->exact 0.8)) #f)
 779(test-equal "eqv?" (eqv? 20 (inexact->exact 20.0)) #t)
 780(test-equal "eqv?" (eqv? 20 20.0) #f)
 781
 782;; numeric comparison involving nan.  we should test both 
 783;; inlined case and applied case
 784(define-syntax test-nan-cmp
 785  (ir-macro-transformer
 786   (lambda (e r c)
 787     (let ((op (cadr e)))
 788       `(begin
 789          (test-equal (format "NaN ~a (inlined)" ',op) (list (,op +nan.0 +nan.0) (,op +nan.0 0) (,op 0 +nan.0))
 790                '(#f #f #f))
 791          (test-equal (format "NaN ~a (applied)" ',op) (list (apply ,op '(+nan.0 +nan.0))
 792                      (apply ,op '(+nan.0 0))
 793                      (apply ,op '(0 +nan.0)))
 794                '(#f #f #f)))))))
 795(test-nan-cmp =)
 796(test-nan-cmp <)
 797(test-nan-cmp <=)
 798(test-nan-cmp >)
 799(test-nan-cmp >=)
 800
 801;; the following tests combine instructions for comparison.
 802(let ((zz #f))
 803  (set! zz 3.14)  ;; prevent the compiler from optimizing constants
 804
 805  (test-equal "NUMEQF" (list (= 3.14 zz) (= zz 3.14) (= 3.15 zz) (= zz 3.15))
 806         '(#t #t #f #f))
 807  (test-equal "NLTF" (list (< 3.14 zz) (< zz 3.14)
 808               (< 3.15 zz) (< zz 3.15)
 809               (< 3.13 zz) (< zz 3.13))
 810         '(#f #f #f #t #t #f))
 811  (test-equal "NLEF" (list (<= 3.14 zz) (<= zz 3.14)
 812               (<= 3.15 zz) (<= zz 3.15)
 813               (<= 3.13 zz) (<= zz 3.13))
 814         '(#t #t #f #t #t #f))
 815  (test-equal "NGTF" (list (> 3.14 zz) (> zz 3.14)
 816               (> 3.15 zz) (> zz 3.15)
 817               (> 3.13 zz) (> zz 3.13))
 818         '(#f #f #t #f #f #t))
 819  (test-equal "NGEF" (list (>= 3.14 zz) (>= zz 3.14)
 820               (>= 3.15 zz) (>= zz 3.15)
 821               (>= 3.13 zz) (>= zz 3.13))
 822         '(#t #t #t #f #f #t))
 823  )
 824
 825;; Go through number comparison routines.
 826;; assumes a >= b, a > 0, b > 0
 827;; we use apply to prevent inlining.
 828(define (numcmp-test msg eq a b) 
 829  (let ((pp (list a b))
 830        (pm (list a (- b)))
 831        (mp (list (- a) b))
 832        (mm (list (- a) (- b))))
 833    (define (test4 op opname rev results)
 834      (for-each (lambda (result comb args)
 835                  (let ((m (conc msg " " (if rev 'rev "") opname "(" comb ")")))
 836                   (test-equal m (apply op (if rev (reverse args) args)) result)))
 837                results '(++ +- -+ --) (list pp pm mp mm)))
 838    (test4 =  '=  #f (list eq #f #f eq))
 839    (test4 =  '=  #t (list eq #f #f eq))
 840    (test4 >= '>= #f (list #t #t #f eq))
 841    (test4 >= '>= #t (list eq #f #t #t))
 842    (test4 >  '>  #f (list (not eq) #t #f #f))
 843    (test4 >  '>  #t (list #f #f #t (not eq)))
 844    (test4 <= '<= #f (list eq #f #t #t))
 845    (test4 <= '<= #t (list #t #t #f eq))
 846    (test4 <  '<  #f (list #f #f #t (not eq)))
 847    (test4 <  '<  #t (list (not eq) #t #f #f))
 848    ))
 849
 850(numcmp-test "fixnum vs fixnum eq" #t 156 156)
 851(numcmp-test "fixnum vs fixnum ne" #f 878252 73224)
 852(numcmp-test "bignum vs fixnum ne" #f (expt 3 50) 9982425)
 853(numcmp-test "bignum vs bignum eq" #t (expt 3 50) (expt 3 50))
 854(numcmp-test "bignum vs bignum ne" #f (expt 3 50) (expt 3 49))
 855(numcmp-test "flonum vs fixnum eq" #t 314.0 314)
 856(numcmp-test "flonum vs fixnum ne" #f 3140.0 314)
 857(numcmp-test "flonum vs bignum eq" #t (expt 2.0 64) (expt 2 64))
 858(numcmp-test "flonum vs bignum ne" #f (expt 2.0 64) (expt 2 63))
 859(numcmp-test "ratnum vs fixnum ne" #f 13/2 6)
 860(numcmp-test "ratnum vs ratnum eq" #t 3/5 3/5)
 861(numcmp-test "ratnum vs ratnum 1 ne" #f 3/5 4/7)
 862(numcmp-test "ratnum vs ratnum 2 ne" #f 4/5 3/7)
 863(numcmp-test "ratnum vs ratnum 3 ne" #f 4/7 2/5)
 864(numcmp-test "ratnum vs ratnum 4 ne" #f 4/7 3/7)
 865(numcmp-test "ratnum vs flonum eq" #t 3/8 0.375)
 866(numcmp-test "ratnum vs flonum ne" #f 8/9 0.6)
 867(numcmp-test "ratnum vs bignum ne" #f (/ (+ (expt 2 64) 1) 2) (expt 2 63))
 868
 869;; This is from the bug report from Bill Schottsteadt.  Before 0.8.10
 870;; this yielded #t because of the precision loss in fixnum vs ratnum
 871;; comparison.
 872
 873(test-equal "fixnum/ratnum comparison" (= -98781233389595723930250385525631360344437602649022271391716773162526352115087074898920261954897888235939429993829738630297052776667061779065100945771127020439712527398509771853491319737304616607041615012797134365574007368603232768089410097730646360760856052946465578073788924743642391638455649511108051053789425902013657106523269224045822294981391380222050223141347787674321888089837786284947870569165079491411110074602544203383038299901291952931113248943344436935596614205784436844912243069019367149526328612664067719765890897558075277707055756274228634652905751880612235340874976952880431555921814590049070979276358637989837532124647692152520447680373275200239544449293834424643702763974403094033892112967196087310232853165951285609426599617479356206218697586025251765476179158153123631158173662488102357611674821528467825910806391548770908013608889792001203039243914696463472490444573930050190716726220002151679336252008777326482398042427845860796285369622627679324605214987983884122808994422164327311297556122943400093231935477754959547620500784989043704825777186301417894825200797719289692636286337716705491307686644214213732116277102140558505945554566856673724837541141206267647285222293953181717113434757149921850120377706206012113994795124049471433490016083401216757825264766474891405185591236321448744678896448941259668731597494947127423662646933419809756274038044752395708014998820826196523041220918922611359697502638594907608648168849193813197790291360087857093790119162389573209640804111261616771827989939551840471235079945175327536638365874717775169210186608268924244639016270610098894971732892267642318266405837012482726627199088381027028630711279130575230815976484191675172279903609489448225149181063260231957171204855841611039996959582465138269247794842445177715476581512709861409446684911276158067098438009067149531119008707418601627426255891/2063950098473886055933596136103014753954685977787179797499441692283103642150668140884348149132839387663291870239435604463778573480782766958396423322880804442523056530013282118705429274303746421980903580754656364533869319744640130831962767797772323836293079599182477171562218297208495122660799328579852852969560730744211066545295945803939271680397511478811389399527913043145952054883289558914237172406636283114284363301999238526952309439259354223729114988806937903509692118585280437646676248013406270664905997291670857985754768850507766359973207600149782819306010561088246502918148146264806947375101624011387317921439210509902170092173796154464078297852707797984007992277904626058467143192149921546030028316990855470478894515952884526783686210401408859364838148201339959570732480920969000913791571631154267939054105878236201498477027265774680071188764947522112650857013491135901945605796776829525789886482760578142306057177990048751864852763036720112071475134369179525117161001517868525821398753039187062869247457336940152614866298628205010037695017885878296140891234142925514925051385440766473260338168038302226808098439763889250948602137806546736025439919604390464712793474019469457135856879584745805794574609707742445431851999335443724488636749987837445626810087003490329257105472274738811579817454656532496370562155449815456374456838912258383282154811001588175608617475540639254689723629881619252699580383612847920348111900440075645703960104081690968807839189109040568288972353424306876947127635585164905071821419089229871978994388197349499565628906992171901547121903117815637249359328193980583892566359962066242217169190169986105579733710057404319381685578470983838597020624234209884597110721892707818651210378187525863009879314177842634871978427592746452643603586344401223449546482306838947819060455178762434166799996220143825677025686435609179225302671777326568324855229172912876656233006785717920665743720753617646617017219230313226844735567400507490772935145894670445831971526014183234960075574401616682479457962912905141754252265169682318523572680657053374002911007741991220001444440319448034755483178790032581428679303588017268970 0)
 874       #f)
 875
 876
 877;;==================================================================
 878;; Fixnum stuff
 879;;
 880
 881(test-equal "fixnum? fixnum" (fixnum? 0) #t)
 882(test-equal "fixnum? ratnum" (fixnum? 1/2) #f)
 883(test-equal "fixnum? bignum" (fixnum? (expt 2 256)) #f)
 884(test-equal "fixnum? flonum" (fixnum? 3.14) #f)
 885(test-equal "fixnum? compnum" (fixnum? 1+3i) #f)
 886
 887(test-equal "fixnum? greatest"    (fixnum? (greatest-fixnum)) #t)
 888(test-equal "fixnum? greatest+1"  (fixnum? (+ (greatest-fixnum) 1)) #f)
 889(test-equal "fixnum? least"       (fixnum? (least-fixnum)) #t)
 890(test-equal "fixnum? least-1"     (fixnum? (- (least-fixnum) 1)) #f)
 891
 892(test-equal "greatest fixnum & width" (- (ash 1 (fixnum-width)) 1)
 893       (greatest-fixnum))
 894(test-equal "least fixnum & width" (- (ash 1 (fixnum-width)))
 895       (least-fixnum))
 896
 897(test-end)
 898
 899;;==================================================================
 900;; Arithmetics
 901;;
 902
 903;;------------------------------------------------------------------
 904(test-begin "integer addition")
 905
 906(define x #xffffffff00000000ffffffff00000000)
 907(define xx (- x))
 908(define y #x00000002000000000000000200000000)
 909(define yy (- y))
 910(define z #x00000000000000010000000000000001)
 911(test-equal "bignum + bignum" (+ x y)
 912      #x100000001000000010000000100000000)
 913(test-equal "bignum + -bignum" (+ x yy)
 914      #xfffffffd00000000fffffffd00000000)
 915(test-equal "bignum - bignum" (- x z)
 916      #xfffffffefffffffffffffffeffffffff)
 917(test-equal "bignum - bignum" (- (+ x y) y)
 918      x)
 919(test-equal "-bignum + bignum" (+ xx y)
 920      #x-fffffffd00000000fffffffd00000000)
 921(test-equal "-bignum + -bignum" (+ xx yy)
 922      #x-100000001000000010000000100000000)
 923(test-equal "-bignum - bignum" (- xx y)
 924      #x-100000001000000010000000100000000)
 925(test-equal "-bignum - -bignum" (- xx yy)
 926      #x-fffffffd00000000fffffffd00000000)
 927
 928;; This test a possible shortcut in Scm_Add etc.  We use apply
 929;; to avoid operators from being inlined.
 930(test-equal "0 + bignum" (list (apply + (list 0 x)) (apply + (list x 0)))
 931       (list x x))
 932(test-equal "0 - bignum" (list (apply - (list 0 x)) (apply - (list x 0)))
 933       (list (- x) x))
 934(test-equal "0 * bignum" (list (apply * (list 0 x)) (apply * (list x 0)))
 935       (list 0 0))
 936(test-equal "1 * bignum" (list (apply * (list 1 x)) (apply * (list x 1)))
 937       (list x x))
 938(test-equal "bignum / 1" (apply / (list x 1))
 939       x)
 940
 941(test-end)
 942
 943;;------------------------------------------------------------------
 944(test-begin "small immediate integer constants")
 945
 946;; pushing small literal integer on the stack may be done
 947;; by combined instruction PUSHI.  These test if it works.
 948
 949(define (foo a b c d e) (list a b c d e))
 950
 951;; 2^19-1
 952(test-equal "PUSHI" (foo 0 524287 524288 -524287 -524288)
 953              '(0 524287 524288 -524287 -524288))
 954;; 2^51-1
 955(test-equal "PUSHI" (foo 0 2251799813685247 2251799813685248
 956             -2251799813685247 -2251799813685248)
 957              '(0 2251799813685247 2251799813685248
 958                  -2251799813685247 -2251799813685248 ))
 959
 960(test-end)
 961
 962;;------------------------------------------------------------------
 963(test-begin "small immediate integer additions")
 964
 965;; small literal integer x (-2^19 <= x < 2^19 on 32bit architecture)
 966;; in binary addition/subtraction is compiled in special instructuions,
 967;; NUMADDI and NUMSUBI.
 968
 969(define x 2)
 970(test-equal "NUMADDI" (+ 3 x) 5)
 971(test-equal "NUMADDI" (+ x 3) 5)
 972(test-equal "NUMADDI" (+ -1 x) 1)
 973(test-equal "NUMADDI" (+ x -1) 1)
 974(test-equal "NUMSUBI" (- 3 x) 1)
 975(test-equal "NUMSUBI" (- x 3) -1)
 976(test-equal "NUMSUBI" (- -3 x) -5)
 977(test-equal "NUMSUBI" (- x -3) 5)
 978(define x 2.0)
 979(test-equal "NUMADDI" (+ 3 x) 5.0)
 980(test-equal "NUMADDI" (+ x 3) 5.0)
 981(test-equal "NUMADDI" (+ -1 x) 1.0)
 982(test-equal "NUMADDI" (+ x -1) 1.0)
 983(test-equal "NUMSUBI" (- 3 x) 1.0)
 984(test-equal "NUMSUBI" (- x 3) -1.0)
 985(test-equal "NUMSUBI" (- -3 x) -5.0)
 986(test-equal "NUMSUBI" (- x -3) 5.0)
 987(define x #x100000000)
 988(test-equal "NUMADDI" (+ 3 x) #x100000003)
 989(test-equal "NUMADDI" (+ x 3) #x100000003)
 990(test-equal "NUMADDI" (+ -1 x) #xffffffff)
 991(test-equal "NUMADDI" (+ x -1) #xffffffff)
 992(test-equal "NUMSUBI" (- 3 x) #x-fffffffd)
 993(test-equal "NUMSUBI" (- x 3) #xfffffffd)
 994(test-equal "NUMSUBI" (- -3 x) #x-100000003)
 995(test-equal "NUMSUBI" (- x -3) #x100000003)
 996(define x 33/7)
 997(test-equal "NUMADDI" (+ 3 x) 54/7)
 998(test-equal "NUMADDI" (+ x 3) 54/7)
 999(test-equal "NUMADDI" (+ -1 x) 26/7)
 1000(test-equal "NUMADDI" (+ x -1) 26/7)
1001(test-equal "NUMADDI" (- 3 x) -12/7)
1002(test-equal "NUMADDI" (- x 3) 12/7)
1003(test-equal "NUMADDI" (- -3 x) -54/7)
1004(test-equal "NUMADDI" (- x -3) 54/7)
1005
1006(test-equal "NUMADDI" (+ 10 (if #t 20 25)) 30)
1007(test-equal "NUMADDI" (+ (if #t 20 25) 10) 30)
1008(test-equal "NUMADDI" (+ 10 (if #f 20 25)) 35)
1009(test-equal "NUMADDI" (+ (if #f 20 25) 10) 35)
1010(test-equal "NUMADDI" (let ((x #t)) (+ 10 (if x 20 25))) 30)
1011(test-equal "NUMADDI" (let ((x #t)) (+ (if x 20 25) 10)) 30)
1012(test-equal "NUMADDI" (let ((x #f)) (+ 10 (if x 20 25))) 35)
1013(test-equal "NUMADDI" (let ((x #f)) (+ (if x 20 25) 10)) 35)
1014(test-equal "NUMADDI" (+ 10 (do ((x 0 (+ x 1))) ((> x 10) x))) 21)
1015(test-equal "NUMADDI" (+ (do ((x 0 (+ x 1))) ((> x 10) x)) 10) 21)
1016(test-equal "NUMSUBI" (- 10 (if #t 20 25)) -10)
1017(test-equal "NUMSUBI" (- (if #t 20 25) 10) 10)
1018(test-equal "NUMSUBI" (- 10 (if #f 20 25)) -15)
1019(test-equal "NUMSUBI" (- (if #f 20 25) 10) 15)
1020(test-equal "NUMSUBI" (let ((x #t)) (- 10 (if x 20 25))) -10)
1021(test-equal "NUMSUBI" (let ((x #t)) (- (if x 20 25) 10)) 10)
1022(test-equal "NUMSUBI" (let ((x #f)) (- 10 (if x 20 25))) -15)
1023(test-equal "NUMSUBI" (let ((x #f)) (- (if x 20 25) 10)) 15)
1024(test-equal "NUMSUBI" (- 10 (do ((x 0 (+ x 1))) ((> x 10) x))) -1)
1025(test-equal "NUMSUBI" (- (do ((x 0 (+ x 1))) ((> x 10) x)) 10) 1)
1026
1027(test-end)
1028
1029;;------------------------------------------------------------------
1030(test-begin "immediate flonum integer arith")
1031
1032;; tests special instructions for immediate flonum integer arithmetic
1033
1034
1035(define x 2.0)
1036(test-equal "NUMADDF" (+ 3 x) 5.0)
1037(test-equal "NUMADDF" (+ x 3) 5.0)
1038(test-equal "NUMADDF" (+ -1 x) 1.0)
1039(test-equal "NUMADDF" (+ x -1) 1.0)
1040(test-equal "NUMADDF" (+ +i x) 2.0+1.0i)
1041(test-equal "NUMADDF" (+ x +i) 2.0+1.0i)
1042
1043(test-equal "NUMSUBF" (- 3 x) 1.0)
1044(test-equal "NUMSUBF" (- x 3) -1.0)
1045(test-equal "NUMSUBF" (- -3 x) -5.0)
1046(test-equal "NUMSUBF" (- x -3) 5.0)
1047(test-equal "NUMSUBF" (- +i x) -2.0+1.0i)
1048(test-equal "NUMSUBF" (- x +i) 2.0-1.0i)
1049
1050(test-equal "NUMMULF" (* x 2) 4.0)
1051(test-equal "NUMMULF" (* 2 x) 4.0)
1052(test-equal "NUMMULF" (* x 1.5) 3.0)
1053(test-equal "NUMMULF" (* 1.5 x) 3.0)
1054(test-equal "NUMMULF" (* x +i) 0+2.0i)
1055(test-equal "NUMMULF" (* +i x) 0+2.0i)
1056
1057(test-equal "NUMDIVF" (/ x 4) 0.5)
1058(test-equal "NUMDIVF" (/ 4 x) 2.0)
1059(test-equal "NUMDIVF" (/ x 4.0) 0.5)
1060(test-equal "NUMDIVF" (/ 4.0 x) 2.0)
1061(test-equal "NUMDIVF" (/ x +4i) 0.0-0.5i)
1062(test-equal "NUMDIVF" (/ +4i x) 0.0+2.0i)
1063
1064(test-end)
1065
1066;;------------------------------------------------------------------
1067(test-begin "rational number addition")
1068
1069(test-equal "ratnum +" (+ 11/13 21/19) 482/247)
1070(test-equal "ratnum -" (- 11/13 21/19) -64/247)
1071
1072;; tests possible shortcut in Scm_Add etc.
1073(test-equal "ratnum + 0" (list (apply + '(0 11/13)) (apply + '(11/13 0)))
1074       (list 11/13 11/13))
1075(test-equal "ratnum - 0" (list (apply - '(0 11/13)) (apply - '(11/13 0)))
1076       (list -11/13 11/13))
1077(test-equal "ratnum * 0" (list (apply * '(0 11/13)) (apply * '(11/13 0)))
1078       (list 0 0))
1079(test-equal "ratnum * 1" (list (apply * '(1 11/13)) (apply * '(11/13 1)))
1080       (list 11/13 11/13))
1081(test-equal "ratnum / 1" (apply / '(11/13 1))
1082       11/13)
1083
1084(test-end)
1085
1086;;------------------------------------------------------------------
1087(test-begin "promotions in addition")
1088
1089(define-syntax +-tester
1090  (syntax-rules ()
1091    ((_ (+ args ...))
1092     (let ((inline (+ args ...))
1093           (other  (apply + `(,args ...))))
1094       (and (= inline other)
1095            (list inline (exact? inline)))))))
1096
1097(test-equal "+" (+-tester (+)) '(0 #t))
1098(test-equal "+" (+-tester (+ 1)) '(1 #t))
1099(test-equal "+" (+-tester (+ 1 2)) '(3 #t))
1100(test-equal "+" (+-tester (+ 1 2 3)) '(6 #t))
1101(test-equal "+" (+-tester (+ 1/6 1/3 1/2)) '(1 #t))
1102(test-equal "+" (+-tester (+ 1.0)) '(1.0 #f))
1103(test-equal "+" (+-tester (+ 1.0 2)) '(3.0 #f))
1104(test-equal "+" (+-tester (+ 1 2.0)) '(3.0 #f))
1105(test-equal "+" (+-tester (+ 1 2 3.0)) '(6.0 #f))
1106(test-equal "+" (+-tester (+ 1/6 1/3 0.5)) '(1.0 #f))
1107(test-equal "+" (+-tester (+ 1 +i)) '(1+i #t))
1108(test-equal "+" (+-tester (+ 1 2 +i)) '(3+i #t))
1109(test-equal "+" (+-tester (+ +i 1 2)) '(3+i #t))
1110(test-equal "+" (+-tester (+ 1.0 2 +i)) '(3.0+i #f))
1111(test-equal "+" (+-tester (+ +i 1.0 2)) '(3.0+i #f))
1112(test-equal "+" (+-tester (+ 4294967297 1.0)) '(4294967298.0 #f))
1113(test-equal "+" (+-tester (+ 4294967297 1 1.0)) '(4294967299.0 #f))
1114(test-equal "+" (+-tester (+ 4294967297 1.0 -i)) '(4294967298.0-i #f))
1115(test-equal "+" (+-tester (+ -i 4294967297 1.0)) '(4294967298.0-i #f))
1116(test-equal "+" (+-tester (+ 1.0 4294967297 -i)) '(4294967298.0-i #f))
1117
1118(test-end)
1119
1120;;------------------------------------------------------------------
1121(test-begin "integer multiplication")
1122
1123(define (m-result x) (list x (- x) (- x) x x (- x) (- x) x))
1124(define (m-tester x y)
1125  (list (* x y) (* (- x) y) (* x (- y)) (* (- x) (- y))
1126        (apply * (list x y)) (apply * (list (- x) y))
1127        (apply * (list x (- y))) (apply * (list (- x) (- y)))))
1128
1129(test-equal "fix*fix->big[1]" (m-tester 41943 17353)
1130      (m-result 727836879))
1131(test-equal "fix*fix->big[1]" (m-tester 41943 87353)
1132      (m-result 3663846879))
1133(test-equal "fix*fix->big[2]" (m-tester 65536 65536)
1134      (m-result 4294967296))
1135(test-equal "fix*fix->big[2]" (m-tester 4194303 87353)
1136      (m-result 366384949959))
1137(test-equal "fix*big[1]->big[1]" (m-tester 3 1126270821)
1138      (m-result 3378812463))
1139(test-equal "fix*big[1]->big[2]" (m-tester 85746 4294967296)
1140      (m-result 368276265762816))
1141(test-equal "big[1]*fix->big[1]" (m-tester 1126270821 3)
1142      (m-result 3378812463))
1143(test-equal "big[1]*fix->big[2]" (m-tester 4294967296 85746)
1144      (m-result 368276265762816))
1145(test-equal "big[2]*fix->big[2]" (m-tester 535341266467 23)
1146      (m-result 12312849128741))
1147(test-equal "big[1]*big[1]->big[2]" (m-tester 1194726677 1126270821)
1148      (m-result 1345585795375391817))
1149
1150;; Large number multiplication test using Fermat's number
1151;; The decomposition of Fermat's number is taken from
1152;;   http://www.dd.iij4u.or.jp/~okuyamak/Information/Fermat.html
1153(test-equal "fermat(7)" (* 59649589127497217 5704689200685129054721)
1154      (fermat 7))
1155(test-equal "fermat(8)" (* 1238926361552897
1156           93461639715357977769163558199606896584051237541638188580280321)
1157              (fermat 8))
1158(test-equal "fermat(9)" (* 2424833
1159           7455602825647884208337395736200454918783366342657
1160           741640062627530801524787141901937474059940781097519023905821316144415759504705008092818711693940737)
1161              (fermat 9))
1162(test-equal "fermat(10)" (* 45592577
1163           6487031809
1164           4659775785220018543264560743076778192897
1165           130439874405488189727484768796509903946608530841611892186895295776832416251471863574140227977573104895898783928842923844831149032913798729088601617946094119449010595906710130531906171018354491609619193912488538116080712299672322806217820753127014424577
1166           )
1167              (fermat 10))
1168(test-equal "fermat(11)" (* 319489
1169           974849
1170           167988556341760475137
1171           3560841906445833920513
1172           173462447179147555430258970864309778377421844723664084649347019061363579192879108857591038330408837177983810868451546421940712978306134189864280826014542758708589243873685563973118948869399158545506611147420216132557017260564139394366945793220968665108959685482705388072645828554151936401912464931182546092879815733057795573358504982279280090942872567591518912118622751714319229788100979251036035496917279912663527358783236647193154777091427745377038294584918917590325110939381322486044298573971650711059244462177542540706913047034664643603491382441723306598834177
1173           )
1174              (fermat 11))
1175
1176(test-end)
1177
1178;;------------------------------------------------------------------
1179(test-begin "multiplication short cuts")
1180
1181(parameterize ((current-test-comparator eqv?))
1182;; these test shortcut in Scm_Mul
1183;; note the difference of 0 and 0.0
1184  (let1 big (read-from-string "100000000000000000000")
1185        (test-equal "bignum * 0"  (apply * `(,big 0)) 0)
1186        (test-equal "0 * bignum"  (apply * `(0 ,big)) 0)
1187        (test-equal "bignum * 1"  (apply * `(,big 1)) big)
1188        (test-equal "1 * bignum"  (apply * `(1 ,big)) big)
1189  
1190        (test-equal "bignum * 0.0"  (apply * `(,big 0.0)) 0.0)
1191        (test-equal "0.0 * bignum"  (apply * `(0.0 ,big)) 0.0)
1192        (test-equal "bignum * 1.0"  (apply * `(,big 1.0)) 1.0e20)
1193        (test-equal "1.0 * bignum"  (apply * `(1.0 ,big)) 1.0e20)
1194        )
1195
1196(test-equal "ratnum * 0"  (apply * '(1/2 0)) 0)
1197(test-equal "0 * ratnum"  (apply * '(0 1/2)) 0)
1198(test-equal "ratnum * 1"  (apply * '(1/2 1)) 1/2)
1199(test-equal "1 * ratnum"  (apply * '(1 1/2)) 1/2)
1200
1201(test-equal "ratnum * 0.0"  (apply * '(1/2 0.0)) 0.0)
1202(test-equal "0.0 * ratnum"  (apply * '(0.0 1/2)) 0.0)
1203(test-equal "ratnum * 1.0"  (apply * '(1/2 1.0)) 0.5)
1204(test-equal "1.0 * ratnum"  (apply * '(1.0 1/2)) 0.5)
1205
1206;; Fixed for exactness (Gauche represents zero always exactly?)
1207(test-equal "flonum * 0"  (apply * '(3.0 0)) 0.0)
1208(test-equal "0 * flonum"  (apply * '(0 3.0)) 0.0)
1209(test-equal "flonum * 1"  (apply * '(3.0 1)) 3.0)
1210(test-equal "1 * flonum"  (apply * '(1 3.0)) 3.0)
1211
1212(test-equal "flonum * 0.0"  (apply * '(3.0 0.0)) 0.0)
1213(test-equal "0.0 * flonum"  (apply * '(0.0 3.0)) 0.0)
1214(test-equal "flonum * 1.0"  (apply * '(3.0 1.0)) 3.0)
1215(test-equal "1.0 * flonum"  (apply * '(1.0 3.0)) 3.0)
1216
1217(test-equal "compnum * 0" (* 0 +i) 0)
1218(test-equal "0 * compnum" (* +i 0) 0)
1219(test-equal "compnum * 1" (* 1 +i) +i)
1220(test-equal "1 * compnum" (* +i 1) +i)
1221
1222(test-equal "compnum * 0.0" (* 0.0 +i) 0.0)
1223(test-equal "0.0 * compnum" (* +i 0.0) 0.0)
1224(test-equal "compnum * 1.0" (* 1.0 +i) +1.0i)
1225(test-equal "1.0 * compnum" (* +i 1.0) +1.0i))
1226
1227(test-end)
1228
1229;;------------------------------------------------------------------
1230(test-begin "division")
1231
1232(test-equal "exact division" (/ 3 4 5) 3/20)
1233(test-equal "exact division" (/ 9223372036854775808 18446744073709551616)  1/2)
1234(test-equal "exact division" (/ 28153784189046 42)
1235       4692297364841/7)
1236(test-equal "exact division" (/ 42 28153784189046)
1237       7/4692297364841)
1238(test-equal "exact division" (/ 42 -28153784189046)
1239       -7/4692297364841)
1240(test-equal "exact division" (/ -42 -28153784189046)
1241       7/4692297364841)
1242(test-equal "exact reciprocal" (/ 3) 1/3)
1243(test-equal "exact reciprocal" (/ -3) -1/3)
1244(test-equal "exact reciprocal" (/ 6/5) 5/6)
1245(test-equal "exact reciprocal" (/ -6/5) -5/6)
1246(test-equal "exact reciprocal" (/ 4692297364841/7) 7/4692297364841)
1247
1248(define (almost=? x y)
1249  (define (flonum=? x y)
1250    (let ((ax (abs x)) (ay (abs y)))
1251      (< (abs (- x y)) (* (max ax ay) 0.0000000000001))))
1252  (and (flonum=? (car x) (car y))
1253       (flonum=? (cadr x) (cadr y))
1254       (flonum=? (caddr x) (caddr y))
1255       (flonum=? (cadddr x) (cadddr y))
1256       (eq? (list-ref x 4) (list-ref y 4))))
1257
1258(define (d-result x exact?) (list x (- x) (- x) x exact?))
1259(define (d-tester x y)
1260  (list (/ x y) (/ (- x) y) (/ x (- y)) (/ (- x) (- y))
1261        (exact? (/ x y))))
1262
1263;; inexact division
1264(test-equal "exact/inexact -> inexact" (d-tester 13 4.0)
1265      (d-result 3.25 #f))
1266(test-equal "exact/inexact -> inexact" (d-tester 13/2 4.0)
1267      (d-result 1.625 #f))
1268(test-equal "inexact/exact -> inexact" (d-tester 13.0 4)
1269      (d-result 3.25 #f))
1270(test-equal "inexact/exact -> inexact" (d-tester 13.0 4/3)
1271      (d-result 9.75 #f))
1272(test-equal "inexact/inexact -> inexact" (d-tester 13.0 4.0)
1273      (d-result 3.25 #f))
1274
1275;; complex division
1276(test-equal "complex division" (let ((a 3)
1277             (b 4+3i)
1278             (c 7.3))
1279         (- (/ a b c)
1280            (/ (/ a b) c)))
1281       0.0)
1282
1283(test-end)
1284
1285;;------------------------------------------------------------------
1286(test-begin "quotient")
1287
1288(define (q-result x exact?) (list x (- x) (- x) x exact?))
1289(define (q-tester x y)
1290  (list (quotient x y) (quotient (- x) y)
1291        (quotient x (- y)) (quotient (- x) (- y))
1292        (exact? (quotient x y))))
1293
1294
1295;; these uses BignumDivSI -> bignum_sdiv
1296(test-equal "big[1]/fix->fix" (q-tester 727836879 41943) 
1297      (q-result 17353 #t))
1298(test-equal "big[1]/fix->fix" (q-tester 3735928559 27353)
1299      (q-result 136582 #t))
1300(test-equal "big[2]/fix->big[1]" (q-tester 12312849128741 23)
1301      (q-result 535341266467 #t))
1302(test-equal "big[2]/fix->big[2]" (q-tester 12312849128741 1)
1303      (q-result 12312849128741 #t))
1304
1305;; these uses BignumDivSI -> bignum_gdiv
1306(test-equal "big[1]/fix->fix" (q-tester 3663846879 87353)
1307      (q-result 41943 #t))
1308(test-equal "big[2]/fix->fix" (q-tester 705986470884353 36984440)
1309      (q-result 19088743 #t))
1310(test-equal "big[2]/fix->fix" (q-tester 12312849128741 132546)
1311      (q-result 92894912 #t))
1312(test-equal "big[2]/fix->big[1]" (q-tester 425897458766735 164900)
1313      (q-result 2582762030 #t))
1314
1315;; these uses BignumDivRem
1316(test-equal "big[1]/big[1]->fix" (q-tester 4020957098 1952679221)
1317      (q-result 2 #t))
1318(test-equal "big[1]/big[1] -> fix" (q-tester 1952679221 4020957098)
1319      (q-result 0 #t))
1320;; this tests loop in estimation phase
1321(test-equal "big[3]/big[2] -> big[1]" (q-tester #x10000000000000000 #x10000ffff)
1322      (q-result #xffff0001 #t))
1323;; this test goes through a rare case handling code ("add back") in
1324;; the algorithm.
1325(test-equal "big[3]/big[2] -> fix" (q-tester #x7800000000000000 #x80008889ffff)
1326      (q-result #xeffe #t))
1327
1328;; inexact quotient
1329(test-equal "exact/inexact -> inexact" (q-tester 13 4.0)
1330      (q-result 3.0 #f))
1331(test-equal "inexact/exact -> inexact" (q-tester 13.0 4)
1332      (q-result 3.0 #f))
1333(test-equal "inexact/inexact -> inexact" (q-tester 13.0 4.0)
1334      (q-result 3.0 #f))
1335(test-equal "exact/inexact -> inexact" (q-tester 727836879 41943.0)
1336      (q-result 17353.0 #f))
1337(test-equal "inexact/exact -> inexact" (q-tester 727836879.0 41943)
1338      (q-result 17353.0 #f))
1339(test-equal "inexact/inexact -> inexact" (q-tester 727836879.0 41943.0)
1340      (q-result 17353.0 #f))
1341
1342;; Test by fermat numbers
1343(test-equal "fermat(7)" (quotient (fermat 7) 5704689200685129054721)
1344      59649589127497217)
1345(test-equal "fermat(8)" (quotient (fermat 8) 93461639715357977769163558199606896584051237541638188580280321)
1346              1238926361552897)
1347(test-equal "fermat(9)" (quotient (quotient (fermat 9) 7455602825647884208337395736200454918783366342657)
1348                  741640062627530801524787141901937474059940781097519023905821316144415759504705008092818711693940737)
1349              2424833)
1350(test-equal "fermat(10)" (quotient (quotient (quotient (fermat 10)
1351                                      130439874405488189727484768796509903946608530841611892186895295776832416251471863574140227977573104895898783928842923844831149032913798729088601617946094119449010595906710130531906171018354491609619193912488538116080712299672322806217820753127014424577)
1352                            6487031809)
1353                  45592577)
1354              4659775785220018543264560743076778192897)
1355(test-equal "fermat(11)" (quotient (quotient (quotient (quotient (fermat 11)
1356                                                167988556341760475137)
1357                                      173462447179147555430258970864309778377421844723664084649347019061363579192879108857591038330408837177983810868451546421940712978306134189864280826014542758708589243873685563973118948869399158545506611147420216132557017260564139394366945793220968665108959685482705388072645828554151936401912464931182546092879815733057795573358504982279280090942872567591518912118622751714319229788100979251036035496917279912663527358783236647193154777091427745377038294584918917590325110939381322486044298573971650711059244462177542540706913047034664643603491382441723306598834177
1358                                      )
1359                            974849)
1360                  319489)
1361              3560841906445833920513)
1362
1363(test-end)
1364
1365;;------------------------------------------------------------------
1366(test-begin "remainder")
1367
1368(define (r-result x exact?) (list x (- x) x (- x) exact?))
1369(define (r-tester x y)
1370  (list (remainder x y) (remainder (- x) y)
1371        (remainder x (- y)) (remainder (- x) (- y))
1372        (exact? (remainder x y))))
1373
1374;; small int
1375(test-equal "fix rem fix -> fix" (r-tester 13 4)
1376      (r-result 1 #t))
1377(test-equal "fix rem fix -> fix" (r-tester 1234 87935)
1378      (r-result 1234 #t))
1379(test-equal "fix rem big[1] -> fix" (r-tester 12345 3735928559)
1380      (r-result 12345 #t))
1381
1382;; these uses BignumDivSI -> bignum_sdiv
1383(test-equal "big[1] rem fix -> fix" (r-tester 727836879 41943)
1384      (r-result 0 #t))
1385(test-equal "big[1] rem fix -> fix" (r-tester 3735928559 27353)
1386      (r-result 1113 #t))
1387(test-equal "big[2] rem fix -> fix" (r-tester 12312849128756 23)
1388      (r-result 15 #t))
1389(test-equal "big[2] rem fix -> fix" (r-tester 12312849128756 1)
1390      (r-result 0 #t))
1391
1392;; these uses BignumDivSI -> bignum_gdiv
1393(test-equal "big[1] rem fix -> fix" (r-tester 3663846879 87353)
1394      (r-result 0 #t))
1395(test-equal "big[2] rem fix -> fix" (r-tester 705986470884353 36984440)
1396      (r-result 725433 #t))
1397(test-equal "big[2] rem fix -> fix" (r-tester 12312849128741 132546)
1398      (r-result 122789 #t))
1399(test-equal "big[2] rem fix -> fix" (r-tester 425897458766735 164900)
1400      (r-result 19735 #t))
1401
1402;; these uses BignumDivRem
1403(test-equal "big[1] rem big[1] -> fix" (r-tester 4020957098 1952679221)
1404      (r-result 115598656 #t))
1405(test-equal "big[1] rem big[1] -> fix" (r-tester 1952679221 4020957098)
1406      (r-result 1952679221 #t))
1407;; this tests loop in estimation phase
1408(test-equal "big[3] rem big[2] -> big[1]" (r-tester #x10000000000000000 #x10000ffff)
1409      (r-result #xfffe0001 #t))
1410;; this tests "add back" code
1411(test-equal "big[3] rem big[2] -> big[2]" (r-tester #x7800000000000000 #x80008889ffff)
1412      (r-result #x7fffb114effe #t))
1413
1414;; inexact remainder
1415(test-equal "exact rem inexact -> inexact" (r-tester 13 4.0)
1416      (r-result 1.0 #f))
1417(test-equal "inexact rem exact -> inexact" (r-tester 13.0 4)
1418      (r-result 1.0 #f))
1419(test-equal "inexact rem inexact -> inexact" (r-tester 13.0 4.0)
1420      (r-result 1.0 #f))
1421(test-equal "exact rem inexact -> inexact" (r-tester 3735928559 27353.0)
1422      (r-result 1113.0 #f))
1423(test-equal "inexact rem exact -> inexact" (r-tester 3735928559.0 27353)
1424      (r-result 1113.0 #f))
1425(test-equal "inexact rem inexact -> inexact" (r-tester 3735928559.0 27353.0)
1426      (r-result 1113.0 #f))
1427
1428(test-end)
1429
1430;;------------------------------------------------------------------
1431(test-begin "modulo")
1432
1433(define (m-result a b exact?) (list a b (- b) (- a) exact?))
1434(define (m-tester x y)
1435  (list (modulo x y) (modulo (- x) y)
1436        (modulo x (- y)) (modulo (- x) (- y))
1437        (exact? (modulo x y))))
1438
1439;; small int
1440(test-equal "fix mod fix -> fix" (m-tester 13 4)
1441      (m-result 1 3 #t))
1442(test-equal "fix mod fix -> fix" (m-tester 1234 87935)
1443      (m-result 1234 86701 #t))
1444(test-equal "fix mod big[1] -> fix/big" (m-tester 12345 3735928559)
1445      (m-result 12345 3735916214 #t))
1446
1447;; these uses BignumDivSI -> bignum_sdiv
1448(test-equal "big[1] mod fix -> fix" (m-tester 727836879 41943)
1449      (m-result 0 0 #t))
1450(test-equal "big[1] mod fix -> fix" (m-tester 3735928559 27353)
1451      (m-result 1113 26240 #t))
1452(test-equal "big[2] mod fix -> fix" (m-tester 12312849128756 23)
1453      (m-result 15 8 #t))
1454(test-equal "big[2] mod fix -> fix" (m-tester 12312849128756 1)
1455      (m-result 0 0 #t))
1456
1457;; these uses BignumDivSI -> bignum_gdiv
1458(test-equal "big[1] mod fix -> fix" (m-tester 3663846879 87353)
1459      (m-result 0 0 #t))
1460(test-equal "big[2] mod fix -> fix" (m-tester 705986470884353 36984440)
1461      (m-result 725433 36259007 #t))
1462(test-equal "big[2] mod fix -> fix" (m-tester 12312849128741 132546)
1463      (m-result 122789 9757 #t))
1464(test-equal "big[2] mod fix -> fix" (m-tester 425897458766735 164900)
1465      (m-result 19735 145165 #t))
1466
1467;; these uses BignumDivRem
1468(test-equal "big[1] mod big[1] -> fix" (m-tester 4020957098 1952679221)
1469      (m-result 115598656 1837080565 #t))
1470(test-equal "big[1] mod big[1] -> fix" (m-tester 1952679221 4020957098)
1471      (m-result 1952679221 2068277877 #t))
1472;; this tests loop in estimation phase
1473(test-equal "big[3] mod big[2] -> big[1]" (m-tester #x10000000000000000 #x10000ffff)
1474      (m-result #xfffe0001 #x2fffe #t))
1475;; this tests "add back" code
1476(test-equal "big[3] mod big[2] -> big[2]" (m-tester #x7800000000000000 #x80008889ffff)
1477      (m-result #x7fffb114effe #xd7751001 #t))
1478
1479;; inexact modulo
1480(test-equal "exact mod inexact -> inexact" (m-tester 13 4.0)
1481      (m-result 1.0 3.0 #f))
1482(test-equal "inexact mod exact -> inexact" (m-tester 13.0 4)
1483      (m-result 1.0 3.0 #f))
1484(test-equal "inexact mod inexact -> inexact" (m-tester 13.0 4.0)
1485      (m-result 1.0 3.0 #f))
1486(test-equal "exact mod inexact -> inexact" (m-tester 3735928559 27353.0)
1487      (m-result 1113.0 26240.0 #f))
1488(test-equal "inexact mod exact -> inexact" (m-tester 3735928559.0 27353)
1489      (m-result 1113.0 26240.0 #f))
1490(test-equal "inexact mod inexact -> inexact" (m-tester 3735928559.0 27353.0)
1491      (m-result 1113.0 26240.0 #f))
1492
1493;; test by mersenne prime? - code by 'hipster'
1494
1495(define (mersenne-prime? p)
1496  (let ((m (- (expt 2 p) 1)))
1497    (do ((i 3 (+ i 1))
1498         (s 4 (modulo (- (* s s) 2) m)))
1499        ((= i (+ p 1)) (= s 0)))))
1500
1501(test-equal "mersenne prime"
1502       (map mersenne-prime? '(3 5 7 13 17 19 31 61 89 107 127 521 607 1279))
1503       '(#t #t #t #t #t #t #t #t #t #t #t #t #t #t))
1504
1505(test-end)
1506
1507;;------------------------------------------------------------------
1508;; R6RS
1509#|
1510(test-begin "div and mod")
1511
1512(let ()
1513  (define (do-quadrants proc)
1514    (lambda (x y =)
1515      (proc x y =)
1516      (proc (- x) y =)
1517      (proc x (- y) =)
1518      (proc (- x) (- y) =)))
1519
1520  (define (test-div x y =)
1521    (test-equal (format "~a div ~a" x y) (receive (d m) (div-and-mod x y)
1522             (let1 z (+ (* d y) m)
1523               (list (or (= x z) z)
1524                     (or (and (<= 0 m) (< m (abs y))) m))))
1525           '(#t #t)))
1526
1527  (define (test-div0 x y =)
1528    (test-equal (format "~a div0 ~a" x y) (receive (d m) (div0-and-mod0 x y)
1529             (let1 z (+ (* d y) m)
1530               (list (or (= x z) z)
1531                     (or (and (<= (- (abs y)) (* m 2))
1532                              (< (* m 2) (abs y)))
1533                         m))))
1534           '(#t #t)))
1535
1536  ((do-quadrants test-div) 123 10 =)
1537  (parameterize ((current-test-epsilon 1e-10))
1538    ((do-quadrants test-div) 123.0 10.0 =))
1539  ((do-quadrants test-div) (read-from-string "123/7") (read-from-string "10/7") =)
1540  ((do-quadrants test-div) (read-from-string "123/7") 5 =)
1541  ((do-quadrants test-div) 123 (read-from-string "5/7") =)
1542  ((do-quadrants test-div) 130.75 10.5 =)
1543
1544  ((do-quadrants test-div0) 123 10 =)
1545  ((do-quadrants test-div0) 129 10 =)
1546  (parameterize ((current-test-epsilon 1e-10))
1547   ((do-quadrants test-div0) 123.0 10.0 =)
1548   ((do-quadrants test-div0) 129.0 10.0 =))
1549  ((do-quadrants test-div0) (read-from-string "123/7") (read-from-string "10/7") =)
1550  ((do-quadrants test-div0) (read-from-string "129/7") (read-from-string "10/7") =)
1551  ((do-quadrants test-div0) (read-from-string "121/7") 5 =)
1552  ((do-quadrants test-div0) (read-from-string "124/7") 5 =)
1553  ((do-quadrants test-div0) 121 (read-from-string "5/7") =)
1554  ((do-quadrants test-div0) 124 (read-from-string "5/7") =)
1555  ((do-quadrants test-div0) 130.75 10.5 =)
1556  ((do-quadrants test-div0) 129.75 10.5 =)
1557  )
1558
1559(test-end)
1560|#
1561;;------------------------------------------------------------------
1562(test-begin "rounding")
1563
1564(define (round-tester value exactness cei flo tru rou)
1565  (test-equal (string-append "rounding " (number->string value))
1566         (let ((c (ceiling value))
1567               (f (floor value))
1568               (t (truncate value))
1569               (r (round value)))
1570           (list (and (exact? c) (exact? f) (exact? t) (exact? r))
1571                 c f t r))
1572         (list exactness cei flo tru rou)))
1573
1574(round-tester 0  #t 0 0 0 0)
1575(round-tester 3  #t 3 3 3 3)
1576(round-tester -3 #t -3 -3 -3 -3)
1577(round-tester (expt 2 99) #t (expt 2 99) (expt 2 99) (expt 2 99) (expt 2 99))
1578(round-tester (- (expt 2 99)) #t
1579              (- (expt 2 99)) (- (expt 2 99)) (- (expt 2 99)) (- (expt 2 99)))
1580
1581(round-tester 9/4  #t 3 2 2 2)
1582(round-tester -9/4 #t -2 -3 -2 -2)
1583(round-tester 34985495387484938453495/17 #t
1584              2057970316910878732559
1585              2057970316910878732558
1586              2057970316910878732558
1587              2057970316910878732559)
1588(round-tester -34985495387484938453495/17 #t
1589              -2057970316910878732558
1590              -2057970316910878732559
1591              -2057970316910878732558
1592              -2057970316910878732559)
1593
1594(round-tester 35565/2 #t 17783 17782 17782 17782)
1595(round-tester -35565/2 #t -17782 -17783 -17782 -17782)
1596(round-tester 35567/2 #t 17784 17783 17783 17784)
1597(round-tester -35567/2 #t -17783 -17784 -17783 -17784)
1598
1599(test-equal "round->exact" (round->exact 3.4) 3)
1600(test-equal "round->exact" (round->exact 3.5) 4)
1601(test-equal "floor->exact" (floor->exact 3.4) 3)
1602(test-equal "floor->exact" (floor->exact -3.5) -4)
1603(test-equal "ceiling->exact" (ceiling->exact 3.4) 4)
1604(test-equal "ceiling->exact" (ceiling->exact -3.5) -3)
1605(test-equal "truncate->exact" (truncate->exact 3.4) 3)
1606(test-equal "truncate->exact" (truncate->exact -3.5) -3)
1607
1608(test-end)
1609
1610;;------------------------------------------------------------------
1611
1612#|
1613;; Nonstandard and Gauche-specific
1614(test-begin "clamping")
1615
1616(parameterize ((current-test-comparator eqv?))
1617 (test-equal "clamp (1)"   (clamp 1)   1)
1618 (test-equal "clamp (1 #f)" (clamp 1 #f)  1)
1619 (test-equal "clamp (1 #f #f)" (clamp 1 #f #f)  1)
1620 (test-equal "clamp (1.0)"   (clamp 1.0)   1.0)
1621 (test-equal "clamp (1.0 #f)" (clamp 1.0 #f)  1.0)
1622 (test-equal "clamp (1.0 #f #f)" (clamp 1.0 #f #f)  1.0)
1623
1624 (test-equal "clamp (1 0)" (clamp 1 0)   1)
1625 (test-equal "clamp (1 0 #f)" (clamp 1 0 #f) 1)
1626 (test-equal "clamp (1 0 2)" (clamp 1 0 2) 1)
1627 (test-equal "clamp (1 5/4)" (clamp 1 5/4) 5/4)
1628 (test-equal "clamp (1 5/4 #f)" (clamp 1 5/4 #f) 5/4)
1629 (test-equal "clamp (1 #f 5/4)" (clamp 1 #f 5/4) 1)
1630 (test-equal "clamp (1 0 3/4)" (clamp 1 0 3/4) 3/4)
1631 (test-equal "clamp (1 #f 3/4)" (clamp 1 #f 3/4) 3/4)
1632
1633 (test-equal "clamp (1.0 0)" (clamp 1.0 0)   1.0)
1634 (test-equal "clamp (1.0 0 #f)" (clamp 1.0 0 #f) 1.0)
1635 (test-equal "clamp (1.0 0 2)" (clamp 1.0 0 2) 1.0)
1636 (test-equal "clamp (1.0 5/4)" (clamp 1.0 5/4) 1.25)
1637 (test-equal "clamp (1.0 5/4 #f)" (clamp 1.0 5/4 #f) 1.25)
1638 (test-equal "clamp (1.0 #f 5/4)" (clamp 1.0 #f 5/4) 1.0)
1639 (test-equal "clamp (1.0 0 3/4)" (clamp 1.0 0 3/4) 0.75)
1640 (test-equal "clamp (1.0 #f 3/4)" (clamp 1.0 #f 3/4) 0.75)
1641
1642 (test-equal "clamp (1 0.0)" (clamp 1 0.0)   1.0)
1643 (test-equal "clamp (1 0.0 #f)" (clamp 1 0.0 #f) 1.0)
1644 (test-equal "clamp (1 0.0 2)" (clamp 1 0.0 2) 1.0)
1645 (test-equal "clamp (1 0 2.0)" (clamp 1 0 2.0) 1.0)
1646 (test-equal "clamp (1 1.25)" (clamp 1 1.25) 1.25)
1647 (test-equal "clamp (1 #f 1.25)" (clamp 1 #f 1.25) 1.0)
1648 (test-equal "clamp (1 1.25 #f)" (clamp 1 1.25 #f) 1.25)
1649 (test-equal "clamp (1 0.0 3/4)" (clamp 1 0.0 3/4) 0.75)
1650 (test-equal "clamp (1 0 0.75)" (clamp 1 0 0.75) 0.75)
1651
1652 (test-equal "clamp (1 -inf.0 +inf.0)" (clamp 1 -inf.0 +inf.0) 1.0))
1653
1654(test-end)
1655|#
1656
1657;;------------------------------------------------------------------
1658(test-begin "logical operations")
1659
1660(test-equal "ash (fixnum)" (ash #x81 15)           ;fixnum
1661      #x408000)
1662(test-equal "ash (fixnum)" (ash #x408000 -15)
1663      #x81)
1664(test-equal "ash (fixnum)" (ash #x408000 -22)
1665      #x01)
1666(test-equal "ash (fixnum)" (ash #x408000 -23)
1667      0)
1668(test-equal "ash (fixnum)" (ash #x408000 -24)
1669      0)
1670(test-equal "ash (fixnum)" (ash #x408000 -100)
1671      0)
1672(test-equal "ash (fixnum)" (ash #x81 0)
1673      #x81)
1674(test-equal "ash (neg. fixnum)" (ash #x-81 15)  ;negative fixnum
1675      #x-408000)
1676(test-equal "ash (neg. fixnum)" (ash #x-408000 -15)      ;nagative fixnum
1677      #x-81)
1678(test-equal "ash (fixnum)" (ash #x-408000 -22)
1679      -2)
1680(test-equal "ash (fixnum)" (ash #x-408000 -23)
1681      -1)
1682(test-equal "ash (fixnum)" (ash #x-408000 -24)
1683      -1)
1684(test-equal "ash (fixnum)" (ash #x-408000 -100)
1685      -1)
1686(test-equal "ash (fixnum)" (ash #x-408000 0)
1687      #x-408000)
1688
1689
1690(test-equal "ash (fixnum->bignum)" (ash #x81 24)
1691      #x81000000)
1692(test-equal "ash (fixnum->bignum)" (ash #x81 31)
1693      #x4080000000)
1694(test-equal "ash (fixnum->bignum)" (ash #x81 32)
1695      #x8100000000)
1696(test-equal "ash (fixnum->bignum)" (ash #x81 56)
1697      #x8100000000000000)
1698(test-equal "ash (fixnum->bignum)" (ash #x81 63)
1699      #x408000000000000000)
1700(test-equal "ash (fixnum->bignum)" (ash #x81 64)
1701      #x810000000000000000)
1702(test-equal "ash (neg.fixnum->bignum)" (ash #x-81 24)
1703      #x-81000000)
1704(test-equal "ash (neg.fixnum->bignum)" (ash #x-81 31)
1705      #x-4080000000)
1706(test-equal "ash (neg.fixnum->bignum)" (ash #x-81 32)
1707      #x-8100000000)
1708(test-equal "ash (neg.fixnum->bignum)" (ash #x-81 56)
1709      #x-8100000000000000)
1710(test-equal "ash (neg.fixnum->bignum)" (ash #x-81 63)
1711      #x-408000000000000000)
1712(test-equal "ash (neg.fixnum->bignum)" (ash #x-81 64)
1713      #x-810000000000000000)
1714
1715(test-equal "ash (bignum->fixnum)" (ash  #x81000000 -24)
1716      #x81)
1717(test-equal "ash (bignum->fixnum)" (ash  #x81000000 -25)
1718      #x40)
1719(test-equal "ash (bignum->fixnum)" (ash  #x81000000 -31)
1720      1)
1721(test-equal "ash (bignum->fixnum)" (ash  #x81000000 -32)
1722      0)
1723(test-equal "ash (bignum->fixnum)" (ash  #x81000000 -100)
1724      0)
1725(test-equal "ash (bignum->fixnum)" (ash #x4080000000 -31)
1726      #x81)
1727(test-equal "ash (bignum->fixnum)" (ash #x8100000000 -32)
1728      #x81)
1729(test-equal "ash (bignum->fixnum)" (ash #x8100000000 -33)
1730      #x40)
1731(test-equal "ash (bignum->fixnum)" (ash #x8100000000 -39)
1732      1)
1733(test-equal "ash (bignum->fixnum)" (ash #x8100000000 -40)
1734      0)
1735(test-equal "ash (bignum->fixnum)" (ash #x8100000000 -100)
1736      0)
1737(test-equal "ash (bignum->fixnum)" (ash #x8100000000000000 -56)
1738      #x81)
1739(test-equal "ash (bignum->fixnum)" (ash #x408000000000000000 -63)
1740      #x81)
1741(test-equal "ash (bignum->fixnum)" (ash #x408000000000000000 -64)
1742      #x40)
1743(test-equal "ash (bignum->fixnum)" (ash #x408000000000000000 -65)
1744      #x20)
1745(test-equal "ash (bignum->fixnum)" (ash #x408000000000000000 -70)
1746      1)
1747(test-equal "ash (bignum->fixnum)" (ash #x408000000000000000 -71)
1748      0)
1749(test-equal "ash (bignum->fixnum)" (ash #x408000000000000000 -100)
1750      0)
1751
1752(test-equal "ash (neg.bignum->fixnum)" (ash #x-81000000 -24)
1753      #x-81)
1754(test-equal "ash (neg.bignum->fixnum)" (ash #x-81000000 -25)
1755      #x-41)
1756(test-equal "ash (neg.bignum->fixnum)" (ash #x-81000000 -26)
1757      #x-21)
1758(test-equal "ash (neg.bignum->fixnum)" (ash #x-81000000 -31)
1759      -2)
1760(test-equal "ash (neg.bignum->fixnum)" (ash #x-81000000 -32)
1761      -1)
1762(test-equal "ash (neg.bignum->fixnum)" (ash #x-81000000 -33)
1763      -1)
1764(test-equal "ash (neg.bignum->fixnum)" (ash #x-81000000 -100)
1765      -1)
1766(test-equal "ash (neg.bignum->fixnum)" (ash #x-4080000000 -31)
1767      #x-81)
1768(test-equal "ash (neg.bignum->fixnum)" (ash #x-4080000000 -32)
1769      #x-41)
1770(test-equal "ash (neg.bignum->fixnum)" (ash #x-4080000000 -33)
1771      #x-21)
1772(test-equal "ash (neg.bignum->fixnum)" (ash #x-4080000000 -38)
1773      -2)
1774(test-equal "ash (neg.bignum->fixnum)" (ash #x-4080000000 -39)
1775      -1)
1776(test-equal "ash (neg.bignum->fixnum)" (ash #x-4080000000 -100)
1777      -1)
1778(test-equal "ash (neg.bignum->fixnum)" (ash #x-408000000000000000 -63)
1779      #x-81)
1780(test-equal "ash (neg.bignum->fixnum)" (ash #x-408000000000000000 -64)
1781      #x-41)
1782(test-equal "ash (neg.bignum->fixnum)" (ash #x-408000000000000000 -65)
1783      #x-21)
1784(test-equal "ash (neg.bignum->fixnum)" (ash #x-408000000000000000 -70)
1785      -2)
1786(test-equal "ash (neg.bignum->fixnum)" (ash #x-408000000000000000 -71)
1787      -1)
1788(test-equal "ash (neg.bignum->fixnum)" (ash #x-408000000000000000 -72)
1789      -1)
1790
1791(test-equal "ash (bignum->bignum)" (ash #x1234567812345678 4)
1792      #x12345678123456780)
1793(test-equal "ash (bignum->bignum)" (ash #x1234567812345678 60)
1794      #x1234567812345678000000000000000)
1795(test-equal "ash (bignum->bignum)" (ash #x1234567812345678 64)
1796      #x12345678123456780000000000000000)
1797(test-equal "ash (bignum->bignum)" (ash #x1234567812345678 -4)
1798      #x123456781234567)
1799(test-equal "ash (bignum->bignum)" (ash #x1234567812345678 -32)
1800      #x12345678)
1801(test-equal "ash (neg.bignum->bignum)" (ash #x-1234567812345678 -4)
1802      #x-123456781234568)
1803(test-equal "ash (bignum->bignum)" (ash #x-1234567812345678 -32)
1804      #x-12345679)
1805
1806(test-equal "lognot (fixnum)" (lognot 0) -1)
1807(test-equal "lognot (fixnum)" (lognot -1) 0)
1808(test-equal "lognot (fixnum)" (lognot 65535) -65536)
1809(test-equal "lognot (fixnum)" (lognot -65536) 65535)
1810(test-equal "lognot (bignum)" (lognot #x1000000000000000000)
1811      #x-1000000000000000001)
1812(test-equal "lognot (bignum)" (lognot #x-1000000000000000001)
1813      #x1000000000000000000)
1814
1815(test-equal "logand (+fix & 0)" (logand #x123456 0)
1816      0)
1817(test-equal "logand (+big & 0)" (logand #x1234567812345678 0)
1818      0)
1819(test-equal "logand (+fix & -1)" (logand #x123456 -1)
1820      #x123456)
1821(test-equal "logand (+big & -1)" (logand #x1234567812345678 -1)
1822      #x1234567812345678)
1823(test-equal "logand (+fix & +fix)" (logand #xaa55 #x6666)
1824      #x2244)
1825(test-equal "logand (+fix & +big)" (logand #xaa55 #x6666666666)
1826      #x2244)
1827(test-equal "logand (+big & +fix)" (logand #xaa55aa55aa #x6666)
1828      #x4422)
1829(test-equal "logand (+big & +big)" (logand #xaa55aa55aa #x6666666666)
1830      #x2244224422)
1831(test-equal "logand (+big & +big)" (logand #x123456789abcdef #xfedcba987654321fedcba987654321fedcba)
1832      #x103454301aaccaa)
1833(test-equal "logand (+big & +big)" (logand #xaa55ea55aa #x55aa55aa55)
1834      #x400000)
1835(test-equal "logand (+fix & -fix)" (logand #xaa55 #x-6666)
1836      #x8810)
1837(test-equal "logand (+fix & -big)" (logand #xaa55 #x-6666666666)
1838      #x8810)
1839(test-equal "logand (+big & -fix)" (logand #xaa55aa55aa #x-6666)
1840      #xaa55aa118a)
1841(test-equal "logand (+big & -big)" (logand #xaa55aa55aa #x-6666666666)
1842      #x881188118a)
1843(test-equal "logand (+big & -big)" (logand #x123456789abcdef #x-fedcba987654321fedcba987654321fedcba)
1844      #x20002488010146)
1845(test-equal "logand (-fix & +fix)" (logand #x-aa55 #x6666)
1846      #x4422)
1847(test-equal "logand (-fix & +big)" (logand #x-aa55 #x6666666666)
1848      #x6666664422)
1849(test-equal "logand (-big & +fix)" (logand #x-aa55aa55aa #x6666)
1850      #x2246)
1851(test-equal "logand (-big & +big)" (logand #x-aa55aa55aa #x6666666666)
1852      #x4422442246)
1853(test-equal "logand (-big & +big)" (logand #x-123456789abcdef #xfedcba987654321fedcba987654321fedcba)
1854      #xfedcba987654321fedcba884200020541010)
1855(test-equal "logand (-fix & -fix)" (logand #x-aa55 #x-6666)
1856      #x-ee76)
1857(test-equal "logand (-fix & -big)" (logand #x-aa55 #x-6666666666)
1858      #x-666666ee76)
1859(test-equal "logand (-big & -fix)" (logand #x-aa55aa55aa #x-6666)
1860      #x-aa55aa77ee)
1861(test-equal "logand (-big & -big)" (logand #x-aa55aa55aa #x-6666666666)
1862      #x-ee77ee77ee)
1863(test-equal "logand (-big & -big)" (logand #x-123456789abcdef #x-fedcba987654321fedcba987654321fedcba)
1864      #x-fedcba987654321fedcba9a76567a9ffde00)
1865
1866(test-equal "logior (+fix | 0)" (logior #x123456 0)
1867      #x123456)
1868(test-equal "logior (+big | 0)" (logior #x1234567812345678 0)
1869      #x1234567812345678)
1870(test-equal "logior (+fix | -1)" (logior #x123456 -1)
1871      -1)
1872(test-equal "logior (+big | -1)" (logior #x1234567812345678 -1)
1873      -1)
1874(test-equal "logior (+fix | +fix)" (logior #xaa55 #x6666)
1875      #xee77)
1876(test-equal "logior (+fix | +big)" (logior #xaa55 #x6666666666)
1877      #x666666ee77)
1878(test-equal "logior (+big | +fix)" (logior #xaa55aa55aa #x6666)
1879      #xaa55aa77ee)
1880(test-equal "logior (+big | +big)" (logior #xaa55aa55aa #x6666666666)
1881      #xee77ee77ee)
1882(test-equal "logior (+big | +big)" (logior #x123456789abcdef #xfedcba987654321fedcba987654321fedcba)
1883      #xfedcba987654321fedcba9a76567a9ffddff)
1884(test-equal "logior (+fix | -fix)" (logior #xaa55 #x-6666)
1885      #x-4421)
1886(test-equal "logior (+fix | -big)" (logior #xaa55 #x-6666666666)
1887      #x-6666664421)
1888(test-equal "logior (+big | -fix)" (logior #xaa55aa55aa #x-6666)
1889      #x-2246)
1890(test-equal "logior (+big | -big)" (logior #xaa55aa55aa #x-6666666666)
1891      #x-4422442246)
1892(test-equal "logior (+big | -big)" (logior #x123456789abcdef #x-fedcba987654321fedcba987654321fedcba)
1893      #x-fedcba987654321fedcba884200020541011)
1894(test-equal "logior (-fix | +fix)" (logior #x-aa55 #x6666)
1895      #x-8811)
1896(test-equal "logior (-fix | +big)" (logior #x-aa55 #x6666666666)
1897      #x-8811)
1898(test-equal "logior (-big | +fix)" (logior #x-aa55aa55aa #x6666)
1899      #x-aa55aa118a)
1900(test-equal "logior (-big | +big)" (logior #x-aa55aa55aa #x6666666666)
1901      #x-881188118a)
1902(test-equal "logior (-big | +big)" (logior #x-123456789abcdef #xfedcba987654321fedcba987654321fedcba)
1903      #x-20002488010145)
1904(test-equal "logior (-fix | -fix)" (logior #x-aa55 #x-6666)
1905      #x-2245)
1906(test-equal "logior (-fix | -big)" (logior #x-aa55 #x-6666666666)
1907      #x-2245)
1908(test-equal "logior (-big | -fix)" (logior #x-aa55aa55aa #x-6666)
1909      #x-4422)
1910(test-equal "logior (-big | -big)" (logior #x-aa55aa55aa #x-6666666666)
1911      #x-2244224422)
1912(test-equal "logior (-big | -big)" (logior #x-123456789abcdef #x-fedcba987654321fedcba987654321fedcba)
1913      #x-103454301aacca9)
1914
1915(test-equal "logtest" (logtest #xfeedbabe #x10000000)
1916      #t)
1917(test-equal "logtest" (logtest #xfeedbabe #x01100101)
1918      #f)
1919
1920#|
1921
1922;; TODO: We don't have these procedures (yet?). Should there be compat
1923;; versions at the top?
1924(let loop ((a 1)   ; 1, 10, 100, ...
1925           (b 1)   ; 1, 11, 111, ...
1926           (c 2)   ; 10, 101, 1001, ...
1927           (n 1))  ; counter
1928  (when (< n 69)
1929    (test-equal (format "logcount (positive, 100...) ~a" n) (logcount a) 1)
1930    (test-equal (format "logcount (positive, 111...) ~a" n) (logcount b) n)
1931    (test-equal (format "logcount (negative, 100...) ~a" n) (logcount (- a)) (- n 1))
1932    (test-equal (format "logcount (negative, 100..1) ~a" n) (logcount (- c)) 1)
1933    (loop (+ b 1) (+ b b 1) (+ b b 3) (+ n 1))))
1934
1935(test-equal "logbit?" (map (lambda (i) (logbit? i #b10110)) '(0 1 2 3 4 5 6))
1936              '(#f #t #t #f #t #f #f))
1937(test-equal "logbit?" (map (lambda (i) (logbit? i #b-10110)) '(0 1 2 3 4 5 6))
1938              '(#f #t #f #t #f #t #t))
1939
1940(test-equal "copy-bit" (copy-bit 4 #b11000110 #t)
1941      #b11010110)
1942(test-equal "copy-bit" (copy-bit 4 #b11000110 #f)
1943      #b11000110)
1944(test-equal "copy-bit" (copy-bit 6 #b11000110 #f)
1945      #b10000110)
1946
1947(test-equal "bit-field" (bit-field #b1101101010 0 4)
1948      #b1010)
1949(test-equal "bit-field" (bit-field #b1101101010 4 9)
1950      #b10110)
1951
1952(test-equal "copy-bit-field" (copy-bit-field #b1101101010 0 4 0)
1953      #b1101100000)
1954(test-equal "copy-bit-field" (copy-bit-field #b1101101010 0 4 -1)
1955      #b1101101111)
1956(test-equal "copy-bit-field" (copy-bit-field #b1101101010 5 16 -1)
1957      #b1111111111101010)
1958|#
1959
1960(test-equal "integer-length" (integer-length #b10101010)
1961      8)
1962(test-equal "integer-length" (integer-length #b1111)
1963      4)
1964
1965(test-end)
1966
1967;;------------------------------------------------------------------
1968(test-begin "inexact arithmetics")
1969
1970(test-equal "+. (0)" (+.) 0.0)
1971(test-equal "+. (1)" (+. 1) 1.0)
1972(test-equal "+. (1big)" (+. 100000000000000000000) 1.0e20)
1973(test-equal "+. (1rat)" (+. 3/2) 1.5)
1974(test-equal "+. (1cmp)" (+. 1+i) 1.0+i)
1975(test-equal "+. (2)" (+. 0 1) 1.0)
1976(test-equal "+. (2big)" (+. 1 100000000000000000000) 1.0e20)
1977(test-equal "+. (2rat)" (+. 1 1/2) 1.5)
1978(test-equal "+. (many)" (+. 1 2 3 4 5) 15.0)
1979
1980(test-equal "-. (1)" (-. 1) -1.0)
1981(test-equal "-. (1big)" (-. 100000000000000000000) -1.0e20)
1982(test-equal "-. (1rat)" (-. 3/2) -1.5)
1983(test-equal "-. (1cmp)" (-. 1+i) -1.0-i)
1984(test-equal "-. (2)" (-. 0 1) -1.0)
1985(test-equal "-. (2big)" (-. 1 100000000000000000000) -1.0e20)
1986(test-equal "-. (2rat)" (-. 1 1/2) 0.5)
1987(test-equal "-. (many)" (-. 1 2 3 4 5) -13.0)
1988
1989(test-equal "*. (0)" (*.) 1.0)
1990(test-equal "*. (1)" (*. 1) 1.0)
1991(test-equal "*. (1big)" (*. 100000000000000000000) 1.0e20)
1992(test-equal "*. (1rat)" (*. 3/2) 1.5)
1993(test-equal "*. (1cmp)" (*. 1+i) 1.0+i)
1994(test-equal "*. (2)"  (*. 0 1) 0.0)
1995(test-equal "*. (2big)" (*. 1 100000000000000000000) 1.0e20)
1996(test-equal "*. (2rat)" (*. 1 1/2) 0.5)
1997(test-equal "*. (many)" (*. 1 2 3 4 5) 120.0)
1998
1999(test-equal "/. (1)" (/. 1) 1.0)
2000(test-equal "/. (1big)" (/. 100000000000000000000) 1.0e-20)
2001(test-equal "/. (1rat)" (/. 3/2) 0.6666666666666666)
2002(test-equal "/. (1cmp)" (/. 1+i) 0.5-0.5i)
2003(test-equal "/. (2)"  (/. 0 1) 0.0)
2004(test-equal "/. (2big)" (/. 1 100000000000000000000) 1.0e-20)
2005(test-equal "/. (2rat)" (/. 1 1/2) 2.0)
2006(test-equal "/. (many)" (/. 1 2 5) 0.1)
2007
2008(test-end)
2009
2010;;------------------------------------------------------------------
2011(test-begin "sqrt")
2012
2013;; R6RS and R7RS
2014(define (integer-sqrt-tester k)
2015  (test-equal (format "exact-integer-sqrt ~a" k) (receive (s r) (exact-integer-sqrt k)
2016           (list (= k (+ (* s s) r))
2017                 (< k (* (+ s 1) (+ s 1)))))
2018         '(#t #t)))
2019
2020(integer-sqrt-tester 0)
2021(integer-sqrt-tester 1)
2022(integer-sqrt-tester 2)
2023(integer-sqrt-tester 3)
2024(integer-sqrt-tester 4)
2025(integer-sqrt-tester 10)
2026(integer-sqrt-tester (expt 2 32))
2027(integer-sqrt-tester (- (expt 2 53) 1))
2028(integer-sqrt-tester (expt 2 53))
2029(integer-sqrt-tester (+ (expt 2 53) 1))
2030(integer-sqrt-tester 9999999999999999999999999999999999999999999999999999)
2031(integer-sqrt-tester (+ (expt 10 400) 3141592653589)) ; double range overflow
2032
2033(test-error "exact-integer-sqrt -1" (exact-integer-sqrt -1))
2034(test-error "exact-integer-sqrt 1.0" (exact-integer-sqrt 1.0))
2035(test-error "exact-integer-sqrt 1/4" (exact-integer-sqrt (read-from-string "1/4")))
2036
2037(parameterize ((current-test-comparator eqv?))
2038 (test-equal "sqrt, exact" (sqrt 0) 0)
2039 (test-equal "sqrt, exact" (sqrt 16) 4)
2040 (test-equal "sqrt, inexact" (sqrt 16.0) 4.0)
2041 (test-equal "sqrt, inexact" (sqrt -16.0) (read-from-string "+4.0i"))
2042 (test-equal "sqrt, exact" (sqrt (read-from-string "1/16")) (read-from-string "1/4"))
2043 (test-equal "sqrt, inexact" (sqrt (exact->inexact (read-from-string "1/16"))) 0.25))
2044
2045(test-end)
2046
2047;;------------------------------------------------------------------
2048(test-begin "ffx optimization")
2049
2050;; This code is provided by naoya_t to reproduce the FFX bug
2051;; existed until r6714.   The bug was that the ARGP words of
2052;; in-stack continuations were not scanned when flonum register
2053;; bank was cleared.  This code exhibits the case by putting
2054;; the result of (sqrt 2) as an unfinished argument, then calling
2055;; inverse-erf which caused flushing flonum regs (see "NG" line).
2056
2057;; (use math.const)
2058(define-constant pi     3.141592653589793)
2059
2060
2061(let ()
2062  (define *epsilon* 1e-12)
2063  
2064  ;;
2065  ;; normal quantile function (probit function)
2066  ;;
2067  (define (probit p)
2068    (define (probit>0 p)
2069      (* (inverse-erf (- (* p 2) 1)) (sqrt 2))) ;; OK
2070    (if (< p 0)
2071      (- 1 (probit>0 (- p)))
2072      (probit>0 p) ))
2073  
2074  (define (probit p)
2075    (define (probit>0 p)
2076      (* (sqrt 2) (inverse-erf (- (* p 2) 1)))) ;; NG
2077    (if (< p 0)
2078      (- 1 (probit>0 (- p)))
2079      (probit>0 p) ))
2080  
2081  ;;
2082  ;; inverse error function (erf-1)
2083  ;;
2084  (define (inverse-erf z)
2085    (define (calc-next-ck k c)
2086      (let loop ((m 0) (sum 0) (ca c) (cz (reverse c)))
2087        (if (= m k) sum
2088            (loop (+ m 1)
2089                  (+ sum (/. (* (car ca) (car cz)) (+ m 1) (+ m m 1)))
2090                  (cdr ca) (cdr cz)))))
2091    (define (calc-cks k)
2092      (let loop ((i 0) (cks '(1)))
2093        (if (= i k) cks
2094            (loop (+ i 1) (cons (calc-next-ck (+ i 1) cks) cks)))))
2095    (define (calc-ck k) (car (calc-cks k)))
2096    
2097    (define (inverse-erf>0 z)
2098      (let1 r (* pi z z 1/4) ; (pi*z^2)/4
2099        (let loop ((k 0) (cks '(1)) (sum 0) (a 1))
2100          (let1 delta (* a (/ (car cks) (+ k k 1)))
2101            (if (< delta (* sum *epsilon*))
2102              (* 1/2 z (sqrt pi) sum)
2103              (loop (+ k 1)
2104                    (cons (calc-next-ck (+ k 1) cks) cks)
2105                    (+ sum delta)
2106                    (* a r)))))))
2107    
2108    (cond [(< z 0) (- (inverse-erf>0 (- z)))]
2109          [(= z 0) 0]
2110          [else (inverse-erf>0 z)]) )
2111
2112  (define ~= (lambda (x y) (< (abs (- x y)) 1e-7)))
2113  ;;
2114  ;; TEST
2115  ;;
2116  (parameterize ((current-test-comparator ~=))
2117    (test-equal "probit(0.025)" (probit 0.025) -1.959964)
2118    (test-equal "probit(0.975)" (probit 0.975) 1.959964))
2119  )
2120
2121(test-end)
2122
2123(test-exit)
Trap