~ chicken-core (master) /tests/numbers-test-gauche.scm
Trap1;;2;; test numeric system implementation3;;4;; These tests are from Gauche Scheme (v0.9.1), which can be found at5;; http://practical-scheme.net/gauche/index.html6;; Some modifications were made to allow it to be used with the "test"7;; egg for Chicken8;;9;; Copyright (c) 2000-2010 Shiro Kawai <shiro@acm.org>10;;11;; Redistribution and use in source and binary forms, with or without12;; modification, are permitted provided that the following conditions13;; are met:14;;15;; 1. Redistributions of source code must retain the above copyright16;; notice, this list of conditions and the following disclaimer.17;;18;; 2. Redistributions in binary form must reproduce the above copyright19;; notice, this list of conditions and the following disclaimer in the20;; documentation and/or other materials provided with the distribution.21;;22;; 3. Neither the name of the authors nor the names of its contributors23;; may be used to endorse or promote products derived from this24;; software without specific prior written permission.25;;26;; THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS27;; "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT28;; LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR29;; A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT30;; OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,31;; SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED32;; TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR33;; PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF34;; LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING35;; NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS36;; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.37;;3839(include "test.scm")4041(define (exp2 pow)42 (do ((i 0 (+ i 1))43 (m 1 (+ m m)))44 ((>= i pow) m)))4546(define (fermat n) ;Fermat's number47 (+ (expt 2 (expt 2 n)) 1))4849;; Gauche compat5051(import (chicken bitwise) (chicken port) (chicken format) (chicken string) (chicken fixnum))52(import (only (scheme base) exact-integer-sqrt))5354(define (greatest-fixnum) most-positive-fixnum)55(define (least-fixnum) most-negative-fixnum)56(define (fixnum-width) fixnum-precision)5758(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))6364(define-syntax let165 (syntax-rules ()66 ((_ var val forms ...)67 (let ((var val)) forms ...))))6869(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))))))7475(define (read-from-string s) (with-input-from-string s read))7677(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)))8182;; This is probably a bit silly83(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)))8788(test-begin "Gauche numbers test")8990;;==================================================================91;; Reader/writer92;;9394;;------------------------------------------------------------------95(test-begin "integer addition & reader")9697(define (i-tester x)98 (list x (+ x -1 x) (+ x x) (- x) (- (+ x -1 x)) (- 0 x x) (- 0 x x 1)))99100(test-equal "around 2^28"101 (i-tester (exp2 28))102 '(268435456 536870911 536870912103 -268435456 -536870911 -536870912 -536870913))104105(test-equal "around 2^31"106 (i-tester (exp2 31))107 '(2147483648 4294967295 4294967296108 -2147483648 -4294967295 -4294967296 -4294967297))109110(test-equal "around 2^60"111 (i-tester (exp2 60))112 '(1152921504606846976 2305843009213693951 2305843009213693952113 -1152921504606846976 -2305843009213693951 -2305843009213693952114 -2305843009213693953))115116(test-equal "around 2^63"117 (i-tester (exp2 63))118 '(9223372036854775808 18446744073709551615 18446744073709551616119 -9223372036854775808 -18446744073709551615 -18446744073709551616120 -18446744073709551617))121122(test-equal "around 2^127"123 (i-tester (exp2 127))124 '(170141183460469231731687303715884105728125 340282366920938463463374607431768211455126 340282366920938463463374607431768211456127 -170141183460469231731687303715884105728128 -340282366920938463463374607431768211455129 -340282366920938463463374607431768211456130 -340282366920938463463374607431768211457))131132;; test for reader's overflow detection code133(test-equal "peculiarity around 2^32"134 (* 477226729 10) 4772267290)135136(test-equal "radix" (list #b1010101001010101137 #o1234567138 #o12345677654321139 #d123456789140 #d123456789987654321141 #x123456142 #xdeadbeef143 #xDeadBeef)144 '(43605 342391 718048024785145 123456789 123456789987654321146 1193046 3735928559 3735928559))147148(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)155156(test-equal "exactness & radix" (list (exact? #e#xdeadbeef)157 #e#xdeadbeef158 (exact? #x#edeadbeef)159 #x#edeadbeef)160 '(#t 3735928559 #t 3735928559))161(test-equal "inexactness & radix" (list (exact? #i#xdeadbeef)162 #i#xdeadbeef163 (exact? #x#ideadbeef)164 #x#ideadbeef)165 '(#f 3735928559.0 #f 3735928559.0))166167(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)174175(define (radix-tester radix)176 (list177 (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)))))193194(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))229230(test-end)231232;;------------------------------------------------------------------233(test-begin "rational reader")234235(define (rational-test v)236 (if (number? v) (list v (exact? v)) v))237238(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))248249(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 Gauche252 #f)253(test-equal "rational reader" (rational-test (string->number "-3/0")) #;'(-inf.0 #f) ; same as above254 #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)261262(test-error "rational reader" (rational-test (read-from-string "#e3/0")))263(test-error "rational reader" (rational-test (read-from-string "#e-3/0")))264265(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))279280(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))286287(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)290291(test-end)292293;;------------------------------------------------------------------294(test-begin "flonum reader")295296(define (flonum-test v)297 (if (number? v) (list v (inexact? v)) v))298299(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)316317(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))332333(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))342343;; Broken for unknown reasons on Mingw344#;(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)350351352(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))359360(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|)364365(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|)371372(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|)378379(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))385386(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 here389;(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))396397(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)401402;;------------------------------------------------------------------403(test-begin "exact fractional number")404405(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)421422(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)))426427(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))431432(test-end)433434;;------------------------------------------------------------------435(test-begin "complex reader")436437(define (decompose-complex z)438 (cond ((real? z) z)439 ((complex? z)440 (list (real-part z) (imag-part z)))441 (else z)))442443;; 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)468469(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|)477478(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 out483#;(test-equal "complex reader" (decompose-complex (string->number "1/2-1/0i")) '(0.5 -inf.0))484485(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)491492(test-end)493494;;------------------------------------------------------------------495(test-begin "integer writer syntax")496497(define (i-tester2 x)498 (map number->string (i-tester x)))499500(test-equal "around 2^28"501 (i-tester2 (exp2 28))502 '("268435456" "536870911" "536870912"503 "-268435456" "-536870911" "-536870912" "-536870913"))504505(test-equal "around 2^31"506 (i-tester2 (exp2 31))507 '("2147483648" "4294967295" "4294967296"508 "-2147483648" "-4294967295" "-4294967296" "-4294967297"))509510(test-equal "around 2^60"511 (i-tester2 (exp2 60))512 '("1152921504606846976" "2305843009213693951" "2305843009213693952"513 "-1152921504606846976" "-2305843009213693951" "-2305843009213693952"514 "-2305843009213693953"))515516(test-equal "around 2^63"517 (i-tester2 (exp2 63))518 '("9223372036854775808" "18446744073709551615" "18446744073709551616"519 "-9223372036854775808" "-18446744073709551615" "-18446744073709551616"520 "-18446744073709551617"))521522(test-equal "around 2^127"523 (i-tester2 (exp2 127))524 '("170141183460469231731687303715884105728"525 "340282366920938463463374607431768211455"526 "340282366920938463463374607431768211456"527 "-170141183460469231731687303715884105728"528 "-340282366920938463463374607431768211455"529 "-340282366920938463463374607431768211456"530 "-340282366920938463463374607431768211457"))531532(test-end)533534;;==================================================================535;; Conversions536;;537538;; We first test expt, for we need to use it to test exact<->inexact539;; conversion stuff.540(test-begin "expt")541542(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)555556(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)562563(test-end)564565(parameterize ((current-test-epsilon 10e7))566 (test-equal "expt (coercion to inexact)" (expt 2 1/2)567 1.4142135623730951)) ;; NB: pa$ will be tested later568569(test-begin "exact<->inexact")570571(for-each572 (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 ))587588;; 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)600601(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))))629630631(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))635636 (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)))639640;; The following few tests covers RATNUM paths in Scm_GetDouble641(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, but644;; 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)654655(test-end)656657;;==================================================================658;; Predicates659;;660661(test-begin "predicates")662663(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)670671(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)682683(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)693694(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)701702(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)709710(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)724725(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)737738(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)760761(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 )772773774(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)781782;; numeric comparison involving nan. we should test both783;; inlined case and applied case784(define-syntax test-nan-cmp785 (ir-macro-transformer786 (lambda (e r c)787 (let ((op (cadr e)))788 `(begin789 (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 >=)800801;; the following tests combine instructions for comparison.802(let ((zz #f))803 (set! zz 3.14) ;; prevent the compiler from optimizing constants804805 (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 )824825;; Go through number comparison routines.826;; assumes a >= b, a > 0, b > 0827;; 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 ))849850(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))868869;; This is from the bug report from Bill Schottsteadt. Before 0.8.10870;; this yielded #t because of the precision loss in fixnum vs ratnum871;; comparison.872873(test-equal "fixnum/ratnum comparison" (= -98781233389595723930250385525631360344437602649022271391716773162526352115087074898920261954897888235939429993829738630297052776667061779065100945771127020439712527398509771853491319737304616607041615012797134365574007368603232768089410097730646360760856052946465578073788924743642391638455649511108051053789425902013657106523269224045822294981391380222050223141347787674321888089837786284947870569165079491411110074602544203383038299901291952931113248943344436935596614205784436844912243069019367149526328612664067719765890897558075277707055756274228634652905751880612235340874976952880431555921814590049070979276358637989837532124647692152520447680373275200239544449293834424643702763974403094033892112967196087310232853165951285609426599617479356206218697586025251765476179158153123631158173662488102357611674821528467825910806391548770908013608889792001203039243914696463472490444573930050190716726220002151679336252008777326482398042427845860796285369622627679324605214987983884122808994422164327311297556122943400093231935477754959547620500784989043704825777186301417894825200797719289692636286337716705491307686644214213732116277102140558505945554566856673724837541141206267647285222293953181717113434757149921850120377706206012113994795124049471433490016083401216757825264766474891405185591236321448744678896448941259668731597494947127423662646933419809756274038044752395708014998820826196523041220918922611359697502638594907608648168849193813197790291360087857093790119162389573209640804111261616771827989939551840471235079945175327536638365874717775169210186608268924244639016270610098894971732892267642318266405837012482726627199088381027028630711279130575230815976484191675172279903609489448225149181063260231957171204855841611039996959582465138269247794842445177715476581512709861409446684911276158067098438009067149531119008707418601627426255891/2063950098473886055933596136103014753954685977787179797499441692283103642150668140884348149132839387663291870239435604463778573480782766958396423322880804442523056530013282118705429274303746421980903580754656364533869319744640130831962767797772323836293079599182477171562218297208495122660799328579852852969560730744211066545295945803939271680397511478811389399527913043145952054883289558914237172406636283114284363301999238526952309439259354223729114988806937903509692118585280437646676248013406270664905997291670857985754768850507766359973207600149782819306010561088246502918148146264806947375101624011387317921439210509902170092173796154464078297852707797984007992277904626058467143192149921546030028316990855470478894515952884526783686210401408859364838148201339959570732480920969000913791571631154267939054105878236201498477027265774680071188764947522112650857013491135901945605796776829525789886482760578142306057177990048751864852763036720112071475134369179525117161001517868525821398753039187062869247457336940152614866298628205010037695017885878296140891234142925514925051385440766473260338168038302226808098439763889250948602137806546736025439919604390464712793474019469457135856879584745805794574609707742445431851999335443724488636749987837445626810087003490329257105472274738811579817454656532496370562155449815456374456838912258383282154811001588175608617475540639254689723629881619252699580383612847920348111900440075645703960104081690968807839189109040568288972353424306876947127635585164905071821419089229871978994388197349499565628906992171901547121903117815637249359328193980583892566359962066242217169190169986105579733710057404319381685578470983838597020624234209884597110721892707818651210378187525863009879314177842634871978427592746452643603586344401223449546482306838947819060455178762434166799996220143825677025686435609179225302671777326568324855229172912876656233006785717920665743720753617646617017219230313226844735567400507490772935145894670445831971526014183234960075574401616682479457962912905141754252265169682318523572680657053374002911007741991220001444440319448034755483178790032581428679303588017268970 0)874 #f)875876877;;==================================================================878;; Fixnum stuff879;;880881(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)886887(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)891892(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))896897(test-end)898899;;==================================================================900;; Arithmetics901;;902903;;------------------------------------------------------------------904(test-begin "integer addition")905906(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)927928;; This test a possible shortcut in Scm_Add etc. We use apply929;; 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)940941(test-end)942943;;------------------------------------------------------------------944(test-begin "small immediate integer constants")945946;; pushing small literal integer on the stack may be done947;; by combined instruction PUSHI. These test if it works.948949(define (foo a b c d e) (list a b c d e))950951;; 2^19-1952(test-equal "PUSHI" (foo 0 524287 524288 -524287 -524288)953 '(0 524287 524288 -524287 -524288))954;; 2^51-1955(test-equal "PUSHI" (foo 0 2251799813685247 2251799813685248956 -2251799813685247 -2251799813685248)957 '(0 2251799813685247 2251799813685248958 -2251799813685247 -2251799813685248 ))959960(test-end)961962;;------------------------------------------------------------------963(test-begin "small immediate integer additions")964965;; 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.968969(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)10051006(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)10261027(test-end)10281029;;------------------------------------------------------------------1030(test-begin "immediate flonum integer arith")10311032;; tests special instructions for immediate flonum integer arithmetic103310341035(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)10421043(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)10491050(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)10561057(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)10631064(test-end)10651066;;------------------------------------------------------------------1067(test-begin "rational number addition")10681069(test-equal "ratnum +" (+ 11/13 21/19) 482/247)1070(test-equal "ratnum -" (- 11/13 21/19) -64/247)10711072;; 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)10831084(test-end)10851086;;------------------------------------------------------------------1087(test-begin "promotions in addition")10881089(define-syntax +-tester1090 (syntax-rules ()1091 ((_ (+ args ...))1092 (let ((inline (+ args ...))1093 (other (apply + `(,args ...))))1094 (and (= inline other)1095 (list inline (exact? inline)))))))10961097(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))11171118(test-end)11191120;;------------------------------------------------------------------1121(test-begin "integer multiplication")11221123(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)))))11281129(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))11491150;; Large number multiplication test using Fermat's number1151;; The decomposition of Fermat's number is taken from1152;; http://www.dd.iij4u.or.jp/~okuyamak/Information/Fermat.html1153(test-equal "fermat(7)" (* 59649589127497217 5704689200685129054721)1154 (fermat 7))1155(test-equal "fermat(8)" (* 12389263615528971156 93461639715357977769163558199606896584051237541638188580280321)1157 (fermat 8))1158(test-equal "fermat(9)" (* 24248331159 74556028256478842083373957362004549187833663426571160 741640062627530801524787141901937474059940781097519023905821316144415759504705008092818711693940737)1161 (fermat 9))1162(test-equal "fermat(10)" (* 455925771163 64870318091164 46597757852200185432645607430767781928971165 1304398744054881897274847687965099039466085308416118921868952957768324162514718635741402279775731048958987839288429238448311490329137987290886016179460941194490105959067101305319061710183544916096191939124885381160807122996723228062178207531270144245771166 )1167 (fermat 10))1168(test-equal "fermat(11)" (* 3194891169 9748491170 1679885563417604751371171 35608419064458339205131172 1734624471791475554302589708643097783774218447236640846493470190613635791928791088575910383304088371779838108684515464219407129783061341898642808260145427587085892438736855639731189488693991585455066111474202161325570172605641393943669457932209686651089596854827053880726458285541519364019124649311825460928798157330577955733585049822792800909428725675915189121186227517143192297881009792510360354969172799126635273587832366471931547770914277453770382945849189175903251109393813224860442985739716507110592444621775425407069130470346646436034913824417233065988341771173 )1174 (fermat 11))11751176(test-end)11771178;;------------------------------------------------------------------1179(test-begin "multiplication short cuts")11801181(parameterize ((current-test-comparator eqv?))1182;; these test shortcut in Scm_Mul1183;; note the difference of 0 and 0.01184 (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)11891190 (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 )11951196(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)12001201(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)12051206;; 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)12111212(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)12161217(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)12211222(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))12261227(test-end)12281229;;------------------------------------------------------------------1230(test-begin "division")12311232(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)12471248(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))))12571258(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))))12621263;; inexact division1264(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))12741275;; complex division1276(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)12821283(test-end)12841285;;------------------------------------------------------------------1286(test-begin "quotient")12871288(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))))129312941295;; these uses BignumDivSI -> bignum_sdiv1296(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))13041305;; these uses BignumDivSI -> bignum_gdiv1306(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))13141315;; these uses BignumDivRem1316(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 phase1321(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") in1324;; the algorithm.1325(test-equal "big[3]/big[2] -> fix" (q-tester #x7800000000000000 #x80008889ffff)1326 (q-result #xeffe #t))13271328;; inexact quotient1329(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))13411342;; Test by fermat numbers1343(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 1734624471791475554302589708643097783774218447236640846493470190613635791928791088575910383304088371779838108684515464219407129783061341898642808260145427587085892438736855639731189488693991585455066111474202161325570172605641393943669457932209686651089596854827053880726458285541519364019124649311825460928798157330577955733585049822792800909428725675915189121186227517143192297881009792510360354969172799126635273587832366471931547770914277453770382945849189175903251109393813224860442985739716507110592444621775425407069130470346646436034913824417233065988341771358 )1359 974849)1360 319489)1361 3560841906445833920513)13621363(test-end)13641365;;------------------------------------------------------------------1366(test-begin "remainder")13671368(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))))13731374;; small int1375(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))13811382;; these uses BignumDivSI -> bignum_sdiv1383(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))13911392;; these uses BignumDivSI -> bignum_gdiv1393(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))14011402;; these uses BignumDivRem1403(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 phase1408(test-equal "big[3] rem big[2] -> big[1]" (r-tester #x10000000000000000 #x10000ffff)1409 (r-result #xfffe0001 #t))1410;; this tests "add back" code1411(test-equal "big[3] rem big[2] -> big[2]" (r-tester #x7800000000000000 #x80008889ffff)1412 (r-result #x7fffb114effe #t))14131414;; inexact remainder1415(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))14271428(test-end)14291430;;------------------------------------------------------------------1431(test-begin "modulo")14321433(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))))14381439;; small int1440(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))14461447;; these uses BignumDivSI -> bignum_sdiv1448(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))14561457;; these uses BignumDivSI -> bignum_gdiv1458(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))14661467;; these uses BignumDivRem1468(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 phase1473(test-equal "big[3] mod big[2] -> big[1]" (m-tester #x10000000000000000 #x10000ffff)1474 (m-result #xfffe0001 #x2fffe #t))1475;; this tests "add back" code1476(test-equal "big[3] mod big[2] -> big[2]" (m-tester #x7800000000000000 #x80008889ffff)1477 (m-result #x7fffb114effe #xd7751001 #t))14781479;; inexact modulo1480(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))14921493;; test by mersenne prime? - code by 'hipster'14941495(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)))))15001501(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))15041505(test-end)15061507;;------------------------------------------------------------------1508;; R6RS1509#|1510(test-begin "div and mod")15111512(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) =)))15191520 (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)))15261527 (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)))15351536 ((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 =)15431544 ((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 )15581559(test-end)1560|#1561;;------------------------------------------------------------------1562(test-begin "rounding")15631564(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)))15731574(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)) #t1579 (- (expt 2 99)) (- (expt 2 99)) (- (expt 2 99)) (- (expt 2 99)))15801581(round-tester 9/4 #t 3 2 2 2)1582(round-tester -9/4 #t -2 -3 -2 -2)1583(round-tester 34985495387484938453495/17 #t1584 20579703169108787325591585 20579703169108787325581586 20579703169108787325581587 2057970316910878732559)1588(round-tester -34985495387484938453495/17 #t1589 -20579703169108787325581590 -20579703169108787325591591 -20579703169108787325581592 -2057970316910878732559)15931594(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)15981599(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)16071608(test-end)16091610;;------------------------------------------------------------------16111612#|1613;; Nonstandard and Gauche-specific1614(test-begin "clamping")16151616(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)16231624 (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)16321633 (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)16411642 (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)16511652 (test-equal "clamp (1 -inf.0 +inf.0)" (clamp 1 -inf.0 +inf.0) 1.0))16531654(test-end)1655|#16561657;;------------------------------------------------------------------1658(test-begin "logical operations")16591660(test-equal "ash (fixnum)" (ash #x81 15) ;fixnum1661 #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 fixnum1675 #x-408000)1676(test-equal "ash (neg. fixnum)" (ash #x-408000 -15) ;nagative fixnum1677 #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)168816891690(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)17141715(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)17511752(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)17901791(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)18051806(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)18141815(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)18651866(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)19141915(test-equal "logtest" (logtest #xfeedbabe #x10000000)1916 #t)1917(test-equal "logtest" (logtest #xfeedbabe #x01100101)1918 #f)19191920#|19211922;; TODO: We don't have these procedures (yet?). Should there be compat1923;; 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)) ; counter1928 (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))))19341935(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))19391940(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)19461947(test-equal "bit-field" (bit-field #b1101101010 0 4)1948 #b1010)1949(test-equal "bit-field" (bit-field #b1101101010 4 9)1950 #b10110)19511952(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|#19591960(test-equal "integer-length" (integer-length #b10101010)1961 8)1962(test-equal "integer-length" (integer-length #b1111)1963 4)19641965(test-end)19661967;;------------------------------------------------------------------1968(test-begin "inexact arithmetics")19691970(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)19791980(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)19881989(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)19981999(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)20072008(test-end)20092010;;------------------------------------------------------------------2011(test-begin "sqrt")20122013;; R6RS and R7RS2014(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)))20192020(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 overflow20322033(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")))20362037(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))20442045(test-end)20462047;;------------------------------------------------------------------2048(test-begin "ffx optimization")20492050;; This code is provided by naoya_t to reproduce the FFX bug2051;; existed until r6714. The bug was that the ARGP words of2052;; in-stack continuations were not scanned when flonum register2053;; bank was cleared. This code exhibits the case by putting2054;; the result of (sqrt 2) as an unfinished argument, then calling2055;; inverse-erf which caused flushing flonum regs (see "NG" line).20562057;; (use math.const)2058(define-constant pi 3.141592653589793)205920602061(let ()2062 (define *epsilon* 1e-12)20632064 ;;2065 ;; normal quantile function (probit function)2066 ;;2067 (define (probit p)2068 (define (probit>0 p)2069 (* (inverse-erf (- (* p 2) 1)) (sqrt 2))) ;; OK2070 (if (< p 0)2071 (- 1 (probit>0 (- p)))2072 (probit>0 p) ))20732074 (define (probit p)2075 (define (probit>0 p)2076 (* (sqrt 2) (inverse-erf (- (* p 2) 1)))) ;; NG2077 (if (< p 0)2078 (- 1 (probit>0 (- p)))2079 (probit>0 p) ))20802081 ;;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) sum2088 (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) cks2094 (loop (+ i 1) (cons (calc-next-ck (+ i 1) cks) cks)))))2095 (define (calc-ck k) (car (calc-cks k)))20962097 (define (inverse-erf>0 z)2098 (let1 r (* pi z z 1/4) ; (pi*z^2)/42099 (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)))))))21072108 (cond [(< z 0) (- (inverse-erf>0 (- z)))]2109 [(= z 0) 0]2110 [else (inverse-erf>0 z)]) )21112112 (define ~= (lambda (x y) (< (abs (- x y)) 1e-7)))2113 ;;2114 ;; TEST2115 ;;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 )21202121(test-end)21222123(test-exit)