;;;; numbers.test --- tests guile's numbers -*- scheme -*- ;;;; Copyright (C) 2000, 2001, 2003 Free Software Foundation, Inc. ;;;; ;;;; This library is free software; you can redistribute it and/or ;;;; modify it under the terms of the GNU Lesser General Public ;;;; License as published by the Free Software Foundation; either ;;;; version 2.1 of the License, or (at your option) any later version. ;;;; ;;;; This library is distributed in the hope that it will be useful, ;;;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU ;;;; Lesser General Public License for more details. ;;;; ;;;; You should have received a copy of the GNU Lesser General Public ;;;; License along with this library; if not, write to the Free Software ;;;; Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA (define-module (test-suite test-numbers) #:use-module (test-suite lib) #:use-module (ice-9 documentation)) ;;; ;;; miscellaneous ;;; (define exception:numerical-overflow (cons 'numerical-overflow "^Numerical overflow")) (define (documented? object) (not (not (object-documentation object)))) (define fixnum-bit (inexact->exact (+ (/ (log (+ most-positive-fixnum 1)) (log 2)) 1))) (define fixnum-min most-negative-fixnum) (define fixnum-max most-positive-fixnum) ;; Divine the number of bits in the mantissa of a flonum. ;; We look for when 2.0^i+1.0 gets rounded, ie. the difference between that ;; value and 2.0^k is not 1.0. ;; Of course this assumes flonums have a fixed precision mantissa, but ;; that's the case now and probably into the forseeable future. ;; On an IEEE system, which means pretty much everywhere, the value here is ;; the usual 53. ;; (define dbl-mant-dig (let more ((i 1) (d 2.0)) (if (> i 1024) (error "Oops, cannot determine number of bits in mantissa of inexact")) (let* ((sum (+ 1.0 d)) (diff (- sum d))) (if (= diff 1.0) (more (1+ i) (* 2.0 d)) i)))) ;; like ash, but working on a flonum (define (ash-flo x n) (while (> n 0) (set! x (* 2.0 x)) (set! n (1- n))) (while (< n 0) (set! x (* 0.5 x)) (set! n (1+ n))) x) ;;; ;;; exact? ;;; (with-test-prefix "exact?" (pass-if "documented?" (documented? exact?)) (with-test-prefix "integers" (pass-if "0" (exact? 0)) (pass-if "fixnum-max" (exact? fixnum-max)) (pass-if "fixnum-max + 1" (exact? (+ fixnum-max 1))) (pass-if "fixnum-min" (exact? fixnum-min)) (pass-if "fixnum-min - 1" (exact? (- fixnum-min 1)))) (with-test-prefix "reals" ;; (FIXME: need better examples.) (pass-if "sqrt (fixnum-max^2 - 1)" (eq? #f (exact? (sqrt (- (expt fixnum-max 2) 1))))) (pass-if "sqrt ((fixnum-max+1)^2 - 1)" (eq? #f (exact? (sqrt (- (expt (+ fixnum-max 1) 2) 1))))))) ;;; ;;; odd? ;;; (with-test-prefix "odd?" (pass-if (documented? odd?)) (pass-if (odd? 1)) (pass-if (odd? -1)) (pass-if (not (odd? 0))) (pass-if (not (odd? 2))) (pass-if (not (odd? -2))) (pass-if (odd? (+ (* 2 fixnum-max) 1))) (pass-if (not (odd? (* 2 fixnum-max)))) (pass-if (odd? (- (* 2 fixnum-min) 1))) (pass-if (not (odd? (* 2 fixnum-min))))) ;;; ;;; even? ;;; (with-test-prefix "even?" (pass-if (documented? even?)) (pass-if (even? 2)) (pass-if (even? -2)) (pass-if (even? 0)) (pass-if (not (even? 1))) (pass-if (not (even? -1))) (pass-if (not (even? (+ (* 2 fixnum-max) 1)))) (pass-if (even? (* 2 fixnum-max))) (pass-if (not (even? (- (* 2 fixnum-min) 1)))) (pass-if (even? (* 2 fixnum-min)))) ;;; ;;; inf? and inf ;;; (with-test-prefix "inf?" (pass-if (documented? inf?)) (pass-if (inf? (inf))) ;; FIXME: what are the expected behaviors? ;; (pass-if (inf? (/ 1.0 0.0)) ;; (pass-if (inf? (/ 1 0.0)) (pass-if (not (inf? 0))) (pass-if (not (inf? 42.0))) (pass-if (not (inf? (+ fixnum-max 1)))) (pass-if (not (inf? (- fixnum-min 1))))) ;;; ;;; nan? and nan ;;; (with-test-prefix "nan?" (pass-if (documented? nan?)) (pass-if (nan? (nan))) ;; FIXME: other ways we should be able to generate NaN? (pass-if (not (nan? 0))) (pass-if (not (nan? 42.0))) (pass-if (not (nan? (+ fixnum-max 1)))) (pass-if (not (nan? (- fixnum-min 1))))) ;;; ;;; abs ;;; (with-test-prefix "abs" (pass-if (documented? abs)) (pass-if (zero? (abs 0))) (pass-if (= 1 (abs 1))) (pass-if (= 1 (abs -1))) (pass-if (= (+ fixnum-max 1) (abs (+ fixnum-max 1)))) (pass-if (= (+ (- fixnum-min) 1) (abs (- fixnum-min 1)))) (pass-if (= 0.0 (abs 0.0))) (pass-if (= 1.0 (abs 1.0))) (pass-if (= 1.0 (abs -1.0))) (pass-if (nan? (abs +nan.0))) (pass-if (= +inf.0 (abs +inf.0))) (pass-if (= +inf.0 (abs -inf.0)))) ;;; ;;; quotient ;;; (with-test-prefix "quotient" (expect-fail "documented?" (documented? quotient)) (with-test-prefix "0 / n" (pass-if "n = 1" (eqv? 0 (quotient 0 1))) (pass-if "n = -1" (eqv? 0 (quotient 0 -1))) (pass-if "n = 2" (eqv? 0 (quotient 0 2))) (pass-if "n = fixnum-max" (eqv? 0 (quotient 0 fixnum-max))) (pass-if "n = fixnum-max + 1" (eqv? 0 (quotient 0 (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (eqv? 0 (quotient 0 fixnum-min))) (pass-if "n = fixnum-min - 1" (eqv? 0 (quotient 0 (- fixnum-min 1))))) (with-test-prefix "1 / n" (pass-if "n = 1" (eqv? 1 (quotient 1 1))) (pass-if "n = -1" (eqv? -1 (quotient 1 -1))) (pass-if "n = 2" (eqv? 0 (quotient 1 2))) (pass-if "n = fixnum-max" (eqv? 0 (quotient 1 fixnum-max))) (pass-if "n = fixnum-max + 1" (eqv? 0 (quotient 1 (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (eqv? 0 (quotient 1 fixnum-min))) (pass-if "n = fixnum-min - 1" (eqv? 0 (quotient 1 (- fixnum-min 1))))) (with-test-prefix "-1 / n" (pass-if "n = 1" (eqv? -1 (quotient -1 1))) (pass-if "n = -1" (eqv? 1 (quotient -1 -1))) (pass-if "n = 2" (eqv? 0 (quotient -1 2))) (pass-if "n = fixnum-max" (eqv? 0 (quotient -1 fixnum-max))) (pass-if "n = fixnum-max + 1" (eqv? 0 (quotient -1 (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (eqv? 0 (quotient -1 fixnum-min))) (pass-if "n = fixnum-min - 1" (eqv? 0 (quotient -1 (- fixnum-min 1))))) (with-test-prefix "fixnum-max / n" (pass-if "n = 1" (eqv? fixnum-max (quotient fixnum-max 1))) (pass-if "n = -1" (eqv? (- fixnum-max) (quotient fixnum-max -1))) (pass-if "n = 2" (eqv? fixnum-max (+ (* (quotient fixnum-max 2) 2) 1))) (pass-if "n = fixnum-max" (eqv? 1 (quotient fixnum-max fixnum-max))) (pass-if "n = fixnum-max + 1" (eqv? 0 (quotient fixnum-max (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (eqv? 0 (quotient fixnum-max fixnum-min))) (pass-if "n = fixnum-min - 1" (eqv? 0 (quotient fixnum-max (- fixnum-min 1))))) (with-test-prefix "(fixnum-max + 1) / n" (pass-if "n = 1" (eqv? (+ fixnum-max 1) (quotient (+ fixnum-max 1) 1))) (pass-if "n = -1" (eqv? (- (+ fixnum-max 1)) (quotient (+ fixnum-max 1) -1))) (pass-if "n = 2" (eqv? (+ fixnum-max 1) (* (quotient (+ fixnum-max 1) 2) 2))) (pass-if "n = fixnum-max" (eqv? 1 (quotient (+ fixnum-max 1) fixnum-max))) (pass-if "n = fixnum-max + 1" (eqv? 1 (quotient (+ fixnum-max 1) (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (eqv? -1 (quotient (+ fixnum-max 1) fixnum-min))) (pass-if "n = fixnum-min - 1" (eqv? 0 (quotient (+ fixnum-max 1) (- fixnum-min 1))))) (with-test-prefix "fixnum-min / n" (pass-if "n = 1" (eqv? fixnum-min (quotient fixnum-min 1))) (pass-if "n = -1" (eqv? (- fixnum-min) (quotient fixnum-min -1))) (pass-if "n = 2" (eqv? fixnum-min (* (quotient fixnum-min 2) 2))) (pass-if "n = fixnum-max" (eqv? -1 (quotient fixnum-min fixnum-max))) (pass-if "n = fixnum-max + 1" (eqv? -1 (quotient fixnum-min (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (eqv? 1 (quotient fixnum-min fixnum-min))) (pass-if "n = fixnum-min - 1" (eqv? 0 (quotient fixnum-min (- fixnum-min 1))))) (with-test-prefix "(fixnum-min - 1) / n" (pass-if "n = 1" (eqv? (- fixnum-min 1) (quotient (- fixnum-min 1) 1))) (pass-if "n = -1" (eqv? (- (- fixnum-min 1)) (quotient (- fixnum-min 1) -1))) (pass-if "n = 2" (eqv? fixnum-min (* (quotient (- fixnum-min 1) 2) 2))) (pass-if "n = fixnum-max" (eqv? -1 (quotient (- fixnum-min 1) fixnum-max))) (pass-if "n = fixnum-max + 1" (eqv? -1 (quotient (- fixnum-min 1) (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (eqv? 1 (quotient (- fixnum-min 1) fixnum-min))) (pass-if "n = fixnum-min - 1" (eqv? 1 (quotient (- fixnum-min 1) (- fixnum-min 1))))) ;; Positive dividend and divisor (pass-if "35 / 7" (eqv? 5 (quotient 35 7))) ;; Negative dividend, positive divisor (pass-if "-35 / 7" (eqv? -5 (quotient -35 7))) ;; Positive dividend, negative divisor (pass-if "35 / -7" (eqv? -5 (quotient 35 -7))) ;; Negative dividend and divisor (pass-if "-35 / -7" (eqv? 5 (quotient -35 -7))) ;; Are numerical overflows detected correctly? (with-test-prefix "division by zero" (pass-if-exception "(quotient 1 0)" exception:numerical-overflow (quotient 1 0)) (pass-if-exception "(quotient bignum 0)" exception:numerical-overflow (quotient (+ fixnum-max 1) 0))) ;; Are wrong type arguments detected correctly? ) ;;; ;;; remainder ;;; (with-test-prefix "remainder" (expect-fail "documented?" (documented? remainder)) (with-test-prefix "0 / n" (pass-if "n = 1" (eqv? 0 (remainder 0 1))) (pass-if "n = -1" (eqv? 0 (remainder 0 -1))) (pass-if "n = fixnum-max" (eqv? 0 (remainder 0 fixnum-max))) (pass-if "n = fixnum-max + 1" (eqv? 0 (remainder 0 (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (eqv? 0 (remainder 0 fixnum-min))) (pass-if "n = fixnum-min - 1" (eqv? 0 (remainder 0 (- fixnum-min 1))))) (with-test-prefix "1 / n" (pass-if "n = 1" (eqv? 0 (remainder 1 1))) (pass-if "n = -1" (eqv? 0 (remainder 1 -1))) (pass-if "n = fixnum-max" (eqv? 1 (remainder 1 fixnum-max))) (pass-if "n = fixnum-max + 1" (eqv? 1 (remainder 1 (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (eqv? 1 (remainder 1 fixnum-min))) (pass-if "n = fixnum-min - 1" (eqv? 1 (remainder 1 (- fixnum-min 1))))) (with-test-prefix "-1 / n" (pass-if "n = 1" (eqv? 0 (remainder -1 1))) (pass-if "n = -1" (eqv? 0 (remainder -1 -1))) (pass-if "n = fixnum-max" (eqv? -1 (remainder -1 fixnum-max))) (pass-if "n = fixnum-max + 1" (eqv? -1 (remainder -1 (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (eqv? -1 (remainder -1 fixnum-min))) (pass-if "n = fixnum-min - 1" (eqv? -1 (remainder -1 (- fixnum-min 1))))) (with-test-prefix "fixnum-max / n" (pass-if "n = 1" (eqv? 0 (remainder fixnum-max 1))) (pass-if "n = -1" (eqv? 0 (remainder fixnum-max -1))) (pass-if "n = fixnum-max" (eqv? 0 (remainder fixnum-max fixnum-max))) (pass-if "n = fixnum-max + 1" (eqv? fixnum-max (remainder fixnum-max (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (eqv? fixnum-max (remainder fixnum-max fixnum-min))) (pass-if "n = fixnum-min - 1" (eqv? fixnum-max (remainder fixnum-max (- fixnum-min 1))))) (with-test-prefix "(fixnum-max + 1) / n" (pass-if "n = 1" (eqv? 0 (remainder (+ fixnum-max 1) 1))) (pass-if "n = -1" (eqv? 0 (remainder (+ fixnum-max 1) -1))) (pass-if "n = fixnum-max" (eqv? 1 (remainder (+ fixnum-max 1) fixnum-max))) (pass-if "n = fixnum-max + 1" (eqv? 0 (remainder (+ fixnum-max 1) (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (eqv? 0 (remainder (+ fixnum-max 1) fixnum-min))) (pass-if "n = fixnum-min - 1" (eqv? (+ fixnum-max 1) (remainder (+ fixnum-max 1) (- fixnum-min 1))))) (with-test-prefix "fixnum-min / n" (pass-if "n = 1" (eqv? 0 (remainder fixnum-min 1))) (pass-if "n = -1" (eqv? 0 (remainder fixnum-min -1))) (pass-if "n = fixnum-max" (eqv? -1 (remainder fixnum-min fixnum-max))) (pass-if "n = fixnum-max + 1" (eqv? 0 (remainder fixnum-min (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (eqv? 0 (remainder fixnum-min fixnum-min))) (pass-if "n = fixnum-min - 1" (eqv? fixnum-min (remainder fixnum-min (- fixnum-min 1))))) (with-test-prefix "(fixnum-min - 1) / n" (pass-if "n = 1" (eqv? 0 (remainder (- fixnum-min 1) 1))) (pass-if "n = -1" (eqv? 0 (remainder (- fixnum-min 1) -1))) (pass-if "n = fixnum-max" (eqv? -2 (remainder (- fixnum-min 1) fixnum-max))) (pass-if "n = fixnum-max + 1" (eqv? -1 (remainder (- fixnum-min 1) (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (eqv? -1 (remainder (- fixnum-min 1) fixnum-min))) (pass-if "n = fixnum-min - 1" (eqv? 0 (remainder (- fixnum-min 1) (- fixnum-min 1))))) ;; Positive dividend and divisor (pass-if "35 / 7" (eqv? 0 (remainder 35 7))) ;; Negative dividend, positive divisor (pass-if "-35 / 7" (eqv? 0 (remainder -35 7))) ;; Positive dividend, negative divisor (pass-if "35 / -7" (eqv? 0 (remainder 35 -7))) ;; Negative dividend and divisor (pass-if "-35 / -7" (eqv? 0 (remainder -35 -7))) ;; Are numerical overflows detected correctly? (with-test-prefix "division by zero" (pass-if-exception "(remainder 1 0)" exception:numerical-overflow (remainder 1 0)) (pass-if-exception "(remainder bignum 0)" exception:numerical-overflow (remainder (+ fixnum-max 1) 0))) ;; Are wrong type arguments detected correctly? ) ;;; ;;; modulo ;;; (with-test-prefix "modulo" (expect-fail "documented?" (documented? modulo)) (with-test-prefix "0 % n" (pass-if "n = 1" (eqv? 0 (modulo 0 1))) (pass-if "n = -1" (eqv? 0 (modulo 0 -1))) (pass-if "n = fixnum-max" (eqv? 0 (modulo 0 fixnum-max))) (pass-if "n = fixnum-max + 1" (eqv? 0 (modulo 0 (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (eqv? 0 (modulo 0 fixnum-min))) (pass-if "n = fixnum-min - 1" (eqv? 0 (modulo 0 (- fixnum-min 1))))) (with-test-prefix "1 % n" (pass-if "n = 1" (eqv? 0 (modulo 1 1))) (pass-if "n = -1" (eqv? 0 (modulo 1 -1))) (pass-if "n = fixnum-max" (eqv? 1 (modulo 1 fixnum-max))) (pass-if "n = fixnum-max + 1" (eqv? 1 (modulo 1 (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (eqv? (+ fixnum-min 1) (modulo 1 fixnum-min))) (pass-if "n = fixnum-min - 1" (eqv? fixnum-min (modulo 1 (- fixnum-min 1))))) (with-test-prefix "-1 % n" (pass-if "n = 1" (eqv? 0 (modulo -1 1))) (pass-if "n = -1" (eqv? 0 (modulo -1 -1))) (pass-if "n = fixnum-max" (eqv? (- fixnum-max 1) (modulo -1 fixnum-max))) (pass-if "n = fixnum-max + 1" (eqv? fixnum-max (modulo -1 (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (eqv? -1 (modulo -1 fixnum-min))) (pass-if "n = fixnum-min - 1" (eqv? -1 (modulo -1 (- fixnum-min 1))))) (with-test-prefix "fixnum-max % n" (pass-if "n = 1" (eqv? 0 (modulo fixnum-max 1))) (pass-if "n = -1" (eqv? 0 (modulo fixnum-max -1))) (pass-if "n = fixnum-max" (eqv? 0 (modulo fixnum-max fixnum-max))) (pass-if "n = fixnum-max + 1" (eqv? fixnum-max (modulo fixnum-max (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (eqv? -1 (modulo fixnum-max fixnum-min))) (pass-if "n = fixnum-min - 1" (eqv? -2 (modulo fixnum-max (- fixnum-min 1))))) (with-test-prefix "(fixnum-max + 1) % n" (pass-if "n = 1" (eqv? 0 (modulo (+ fixnum-max 1) 1))) (pass-if "n = -1" (eqv? 0 (modulo (+ fixnum-max 1) -1))) (pass-if "n = fixnum-max" (eqv? 1 (modulo (+ fixnum-max 1) fixnum-max))) (pass-if "n = fixnum-max + 1" (eqv? 0 (modulo (+ fixnum-max 1) (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (eqv? 0 (modulo (+ fixnum-max 1) fixnum-min))) (pass-if "n = fixnum-min - 1" (eqv? -1 (modulo (+ fixnum-max 1) (- fixnum-min 1))))) (with-test-prefix "fixnum-min % n" (pass-if "n = 1" (eqv? 0 (modulo fixnum-min 1))) (pass-if "n = -1" (eqv? 0 (modulo fixnum-min -1))) (pass-if "n = fixnum-max" (eqv? (- fixnum-max 1) (modulo fixnum-min fixnum-max))) (pass-if "n = fixnum-max + 1" (eqv? 0 (modulo fixnum-min (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (eqv? 0 (modulo fixnum-min fixnum-min))) (pass-if "n = fixnum-min - 1" (eqv? fixnum-min (modulo fixnum-min (- fixnum-min 1))))) (with-test-prefix "(fixnum-min - 1) % n" (pass-if "n = 1" (eqv? 0 (modulo (- fixnum-min 1) 1))) (pass-if "n = -1" (eqv? 0 (modulo (- fixnum-min 1) -1))) (pass-if "n = fixnum-max" (eqv? (- fixnum-max 2) (modulo (- fixnum-min 1) fixnum-max))) (pass-if "n = fixnum-max + 1" (eqv? fixnum-max (modulo (- fixnum-min 1) (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (eqv? -1 (modulo (- fixnum-min 1) fixnum-min))) (pass-if "n = fixnum-min - 1" (eqv? 0 (modulo (- fixnum-min 1) (- fixnum-min 1))))) ;; Positive dividend and divisor (pass-if "13 % 4" (eqv? 1 (modulo 13 4))) (pass-if "2177452800 % 86400" (eqv? 0 (modulo 2177452800 86400))) ;; Negative dividend, positive divisor (pass-if "-13 % 4" (eqv? 3 (modulo -13 4))) (pass-if "-2177452800 % 86400" (eqv? 0 (modulo -2177452800 86400))) ;; Positive dividend, negative divisor (pass-if "13 % -4" (eqv? -3 (modulo 13 -4))) (pass-if "2177452800 % -86400" (eqv? 0 (modulo 2177452800 -86400))) ;; Negative dividend and divisor (pass-if "-13 % -4" (eqv? -1 (modulo -13 -4))) (pass-if "-2177452800 % -86400" (eqv? 0 (modulo -2177452800 -86400))) ;; Are numerical overflows detected correctly? (with-test-prefix "division by zero" (pass-if-exception "(modulo 1 0)" exception:numerical-overflow (modulo 1 0)) (pass-if-exception "(modulo bignum 0)" exception:numerical-overflow (modulo (+ fixnum-max 1) 0))) ;; Are wrong type arguments detected correctly? ) ;;; ;;; gcd ;;; (with-test-prefix "gcd" (expect-fail "documented?" (documented? gcd)) (with-test-prefix "(0 n)" (pass-if "n = 0" (eqv? 0 (gcd 0 0))) (pass-if "n = 1" (eqv? 1 (gcd 0 1))) (pass-if "n = -1" (eqv? 1 (gcd 0 -1))) (pass-if "n = fixnum-max" (eqv? fixnum-max (gcd 0 fixnum-max))) (pass-if "n = fixnum-max + 1" (eqv? (+ fixnum-max 1) (gcd 0 (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (eqv? (- fixnum-min) (gcd 0 fixnum-min))) (pass-if "n = fixnum-min - 1" (eqv? (- (- fixnum-min 1)) (gcd 0 (- fixnum-min 1))))) (with-test-prefix "(n 0)" (pass-if "n = 2^128 * fixnum-max" (eqv? (ash fixnum-max 128) (gcd (ash fixnum-max 128) 0)))) (with-test-prefix "(1 n)" (pass-if "n = 0" (eqv? 1 (gcd 1 0))) (pass-if "n = 1" (eqv? 1 (gcd 1 1))) (pass-if "n = -1" (eqv? 1 (gcd 1 -1))) (pass-if "n = fixnum-max" (eqv? 1 (gcd 1 fixnum-max))) (pass-if "n = fixnum-max + 1" (eqv? 1 (gcd 1 (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (eqv? 1 (gcd 1 fixnum-min))) (pass-if "n = fixnum-min - 1" (eqv? 1 (gcd 1 (- fixnum-min 1))))) (with-test-prefix "(-1 n)" (pass-if "n = 0" (eqv? 1 (gcd -1 0))) (pass-if "n = 1" (eqv? 1 (gcd -1 1))) (pass-if "n = -1" (eqv? 1 (gcd -1 -1))) (pass-if "n = fixnum-max" (eqv? 1 (gcd -1 fixnum-max))) (pass-if "n = fixnum-max + 1" (eqv? 1 (gcd -1 (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (eqv? 1 (gcd -1 fixnum-min))) (pass-if "n = fixnum-min - 1" (eqv? 1 (gcd -1 (- fixnum-min 1))))) (with-test-prefix "(fixnum-max n)" (pass-if "n = 0" (eqv? fixnum-max (gcd fixnum-max 0))) (pass-if "n = 1" (eqv? 1 (gcd fixnum-max 1))) (pass-if "n = -1" (eqv? 1 (gcd fixnum-max -1))) (pass-if "n = fixnum-max" (eqv? fixnum-max (gcd fixnum-max fixnum-max))) (pass-if "n = fixnum-max + 1" (eqv? 1 (gcd fixnum-max (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (eqv? 1 (gcd fixnum-max fixnum-min))) (pass-if "n = fixnum-min - 1" (eqv? 1 (gcd fixnum-max (- fixnum-min 1))))) (with-test-prefix "((+ fixnum-max 1) n)" (pass-if "n = 0" (eqv? (+ fixnum-max 1) (gcd (+ fixnum-max 1) 0))) (pass-if "n = 1" (eqv? 1 (gcd (+ fixnum-max 1) 1))) (pass-if "n = -1" (eqv? 1 (gcd (+ fixnum-max 1) -1))) (pass-if "n = fixnum-max" (eqv? 1 (gcd (+ fixnum-max 1) fixnum-max))) (pass-if "n = fixnum-max + 1" (eqv? (+ fixnum-max 1) (gcd (+ fixnum-max 1) (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (eqv? (+ fixnum-max 1) (gcd (+ fixnum-max 1) fixnum-min))) (pass-if "n = fixnum-min - 1" (eqv? 1 (gcd (+ fixnum-max 1) (- fixnum-min 1))))) (with-test-prefix "(fixnum-min n)" (pass-if "n = 0" (eqv? (- fixnum-min) (gcd fixnum-min 0))) (pass-if "n = 1" (eqv? 1 (gcd fixnum-min 1))) (pass-if "n = -1" (eqv? 1 (gcd fixnum-min -1))) (pass-if "n = fixnum-max" (eqv? 1 (gcd fixnum-min fixnum-max))) (pass-if "n = fixnum-max + 1" (eqv? (+ fixnum-max 1) (gcd fixnum-min (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (eqv? (- fixnum-min) (gcd fixnum-min fixnum-min))) (pass-if "n = fixnum-min - 1" (eqv? 1 (gcd fixnum-min (- fixnum-min 1))))) (with-test-prefix "((- fixnum-min 1) n)" (pass-if "n = 0" (eqv? (- (- fixnum-min 1)) (gcd (- fixnum-min 1) 0))) (pass-if "n = 1" (eqv? 1 (gcd (- fixnum-min 1) 1))) (pass-if "n = -1" (eqv? 1 (gcd (- fixnum-min 1) -1))) (pass-if "n = fixnum-max" (eqv? 1 (gcd (- fixnum-min 1) fixnum-max))) (pass-if "n = fixnum-max + 1" (eqv? 1 (gcd (- fixnum-min 1) (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (eqv? 1 (gcd (- fixnum-min 1) fixnum-min))) (pass-if "n = fixnum-min - 1" (eqv? (- (- fixnum-min 1)) (gcd (- fixnum-min 1) (- fixnum-min 1))))) ;; Are wrong type arguments detected correctly? ) ;;; ;;; lcm ;;; (with-test-prefix "lcm" ;; FIXME: more tests? ;; (some of these are already in r4rs.test) (expect-fail (documented? lcm)) (pass-if (= (lcm) 1)) (pass-if (= (lcm 32 -36) 288)) (let ((big-n 115792089237316195423570985008687907853269984665640564039457584007913129639936) ; 2 ^ 256 (lcm-of-big-n-and-11 1273712981610478149659280835095566986385969831322046204434033424087044426039296)) (pass-if (= lcm-of-big-n-and-11 (lcm big-n 11))) (pass-if (= lcm-of-big-n-and-11 (lcm 11 big-n 11))))) ;;; ;;; number->string ;;; (with-test-prefix "number->string" (let ((num->str->num (lambda (n radix) (string->number (number->string n radix) radix)))) (pass-if (documented? number->string)) (pass-if (string=? (number->string 0) "0")) (pass-if (string=? (number->string 171) "171")) (pass-if (= (+ fixnum-max 1) (num->str->num (+ fixnum-max 1) 10))) (pass-if (= (- fixnum-min 1) (num->str->num (- fixnum-min 1) 10))) (pass-if (= (inf) (num->str->num (inf) 10))) (pass-if (= 1.3 (num->str->num 1.3 10))))) ;;; ;;; string->number ;;; (with-test-prefix "string->number" (pass-if "string->number" (documented? string->number)) (pass-if "non number strings" (for-each (lambda (x) (if (string->number x) (throw 'fail))) '("" "q" "1q" "6+7iq" "8+9q" "10+11" "13+" "18@19q" "20@q" "23@" "+25iq" "26i" "-q" "-iq" "i" "5#.0" "8/" "10#11" ".#" "." "#o.2" "3.4q" "15.16e17q" "18.19e+q" ".q" ".17#18" "10q" "#b2" "#b3" "#b4" "#b5" "#b6" "#b7" "#b8" "#b9" "#ba" "#bb" "#bc" "#bd" "#be" "#bf" "#q" "#b#b1" "#o#o1" "#d#d1" "#x#x1" "#e#e1" "#i#i1" "12@12+0i")) #t) (pass-if "valid number strings" (for-each (lambda (couple) (apply (lambda (x y) (let ((xx (string->number x))) (if (or (eq? xx #f) (not (eqv? xx y))) (begin (pk x y) (throw 'fail))))) couple)) `(;; Radix: ("#b0" 0) ("#B0" 0) ("#b1" 1) ("#B1" 1) ("#o0" 0) ("#O0" 0) ("#o1" 1) ("#O1" 1) ("#o2" 2) ("#O2" 2) ("#o3" 3) ("#O3" 3) ("#o4" 4) ("#O4" 4) ("#o5" 5) ("#O5" 5) ("#o6" 6) ("#O6" 6) ("#o7" 7) ("#O7" 7) ("#d0" 0) ("#D0" 0) ("#d1" 1) ("#D1" 1) ("#d2" 2) ("#D2" 2) ("#d3" 3) ("#D3" 3) ("#d4" 4) ("#D4" 4) ("#d5" 5) ("#D5" 5) ("#d6" 6) ("#D6" 6) ("#d7" 7) ("#D7" 7) ("#d8" 8) ("#D8" 8) ("#d9" 9) ("#D9" 9) ("#xa" 10) ("#Xa" 10) ("#xb" 11) ("#Xb" 11) ("#xc" 12) ("#Xc" 12) ("#xd" 13) ("#Xd" 13) ("#xe" 14) ("#Xe" 14) ("#xf" 15) ("#Xf" 15) ("#b1010" 10) ("#o12345670" 2739128) ("#d1234567890" 1234567890) ("#x1234567890abcdef" 1311768467294899695) ;; Exactness: ("#e1" 1) ("#e1.2" 12/10) ("#i1.1" 1.1) ("#i1" 1.0) ;; Integers: ("1" ,(1+ 0)) ("23" ,(+ 9 9 5)) ("-1" ,(- 0 1)) ("-45" ,(- 0 45)) ("2#" 20.0) ("2##" 200.0) ("12##" 1200.0) ("#b#i100" 4.0) ;; Fractions: ("1/1" 1) ("1/2" 1/2) ("-1/2" -1/2) ("1#/1" 10.0) ("10/1#" 1.0) ("1#/1#" 1.0) ("#e9/10" 9/10) ("#e10/1#" 1) ("#i6/8" 0.75) ("#i1/1" 1.0) ;; Decimal numbers: ;; * ("1e2" 100.0) ("1E2" 100.0) ("1s2" 100.0) ("1S2" 100.0) ("1f2" 100.0) ("1F2" 100.0) ("1d2" 100.0) ("1D2" 100.0) ("1l2" 100.0) ("1L2" 100.0) ("1e+2" 100.0) ("1e-2" 0.01) ;; * . + #* (".1" .1) (".0123456789" 123456789e-10) (".16#" 0.16) (".0123456789e10" 123456789.0) (".16#e3" 160.0) ("#d.3" 0.3) ;; * + . * #* ("3." ,(exact->inexact 3)) ("3.e0" ,(exact->inexact 3)) ("3.1" ,(exact->inexact 31/10)) ("3.1e0" 3.1) ("3.1#" 3.1) ("3.1#e0" 3.1) ;; * + #+ . #* ("3#." 30.0) ("3#.e0" 30.0) ("3#.#" 30.0) ("3#.#e0" 30.0) ;; Complex: ("1@0" 1.0) ("1@+0" 1.0) ("1@-0" 1.0) ("2+3i" ,(+ 2 (* 3 +i))) ("4-5i" ,(- 4 (* 5 +i))) ("1+i" 1+1i) ("1-i" 1-1i) ("+1i" 0+1i) ("-1i" 0-1i) ("+i" +1i) ("-i" -1i))) #t) (pass-if-exception "exponent too big" exception:out-of-range (string->number "12.13e141414"))) ;;; ;;; number? ;;; (with-test-prefix "number?" (pass-if (documented? number?)) (pass-if (number? 0)) (pass-if (number? 7)) (pass-if (number? -7)) (pass-if (number? 1.3)) (pass-if (number? (+ 1 fixnum-max))) (pass-if (number? (- 1 fixnum-min))) (pass-if (number? 3+4i)) (pass-if (not (number? #\a))) (pass-if (not (number? "a"))) (pass-if (not (number? (make-vector 0)))) (pass-if (not (number? (cons 1 2)))) (pass-if (not (number? #t))) (pass-if (not (number? (lambda () #t)))) (pass-if (not (number? (current-input-port))))) ;;; ;;; complex? ;;; (with-test-prefix "complex?" (pass-if (documented? complex?)) (pass-if (complex? 0)) (pass-if (complex? 7)) (pass-if (complex? -7)) (pass-if (complex? (+ 1 fixnum-max))) (pass-if (complex? (- 1 fixnum-min))) (pass-if (complex? 1.3)) (pass-if (complex? 3+4i)) (pass-if (not (complex? #\a))) (pass-if (not (complex? "a"))) (pass-if (not (complex? (make-vector 0)))) (pass-if (not (complex? (cons 1 2)))) (pass-if (not (complex? #t))) (pass-if (not (complex? (lambda () #t)))) (pass-if (not (complex? (current-input-port))))) ;;; ;;; real? ;;; (with-test-prefix "real?" (pass-if (documented? real?)) (pass-if (real? 0)) (pass-if (real? 7)) (pass-if (real? -7)) (pass-if (real? (+ 1 fixnum-max))) (pass-if (real? (- 1 fixnum-min))) (pass-if (real? 1.3)) (pass-if (not (real? 3+4i))) (pass-if (not (real? #\a))) (pass-if (not (real? "a"))) (pass-if (not (real? (make-vector 0)))) (pass-if (not (real? (cons 1 2)))) (pass-if (not (real? #t))) (pass-if (not (real? (lambda () #t)))) (pass-if (not (real? (current-input-port))))) ;;; ;;; rational? (same as real? right now) ;;; (with-test-prefix "rational?" (pass-if (documented? rational?)) (pass-if (rational? 0)) (pass-if (rational? 7)) (pass-if (rational? -7)) (pass-if (rational? (+ 1 fixnum-max))) (pass-if (rational? (- 1 fixnum-min))) (pass-if (rational? 1.3)) (pass-if (not (rational? 3+4i))) (pass-if (not (rational? #\a))) (pass-if (not (rational? "a"))) (pass-if (not (rational? (make-vector 0)))) (pass-if (not (rational? (cons 1 2)))) (pass-if (not (rational? #t))) (pass-if (not (rational? (lambda () #t)))) (pass-if (not (rational? (current-input-port))))) ;;; ;;; integer? ;;; (with-test-prefix "integer?" (pass-if (documented? integer?)) (pass-if (integer? 0)) (pass-if (integer? 7)) (pass-if (integer? -7)) (pass-if (integer? (+ 1 fixnum-max))) (pass-if (integer? (- 1 fixnum-min))) (pass-if (and (= 3+0i (round 3+0i)) (integer? 3+0i))) (pass-if (and (= 1.0 (round 1.0)) (integer? 1.0))) (pass-if (not (integer? 1.3))) (pass-if (not (integer? 3+4i))) (pass-if (not (integer? #\a))) (pass-if (not (integer? "a"))) (pass-if (not (integer? (make-vector 0)))) (pass-if (not (integer? (cons 1 2)))) (pass-if (not (integer? #t))) (pass-if (not (integer? (lambda () #t)))) (pass-if (not (integer? (current-input-port))))) ;;; ;;; inexact? ;;; (with-test-prefix "inexact?" (pass-if (documented? inexact?)) (pass-if (not (inexact? 0))) (pass-if (not (inexact? 7))) (pass-if (not (inexact? -7))) (pass-if (not (inexact? (+ 1 fixnum-max)))) (pass-if (not (inexact? (- 1 fixnum-min)))) (pass-if (inexact? 1.3)) (pass-if (inexact? 3.1+4.2i)) (pass-if-exception "char" exception:wrong-type-arg (not (inexact? #\a))) (pass-if-exception "string" exception:wrong-type-arg (not (inexact? "a"))) (pass-if-exception "vector" exception:wrong-type-arg (not (inexact? (make-vector 0)))) (pass-if-exception "cons" exception:wrong-type-arg (not (inexact? (cons 1 2)))) (pass-if-exception "bool" exception:wrong-type-arg (not (inexact? #t))) (pass-if-exception "procedure" exception:wrong-type-arg (not (inexact? (lambda () #t)))) (pass-if-exception "port" exception:wrong-type-arg (not (inexact? (current-input-port))))) ;;; ;;; equal? ;;; (with-test-prefix "equal?" (pass-if (documented? equal?)) (pass-if (equal? 0 0)) (pass-if (equal? 7 7)) (pass-if (equal? -7 -7)) (pass-if (equal? (+ 1 fixnum-max) (+ 1 fixnum-max))) (pass-if (equal? (- fixnum-min 1) (- fixnum-min 1))) (pass-if (not (equal? 0 1))) (pass-if (not (equal? fixnum-max (+ 1 fixnum-max)))) (pass-if (not (equal? (+ 1 fixnum-max) fixnum-max))) (pass-if (not (equal? (+ 1 fixnum-max) (+ 2 fixnum-max)))) (pass-if (not (equal? fixnum-min (- fixnum-min 1)))) (pass-if (not (equal? (- fixnum-min 1) fixnum-min))) (pass-if (not (equal? (- fixnum-min 1) (- fixnum-min 2)))) (pass-if (not (equal? (+ fixnum-max 1) (- fixnum-min 1)))) (pass-if (not (equal? (ash 1 256) +inf.0))) (pass-if (not (equal? +inf.0 (ash 1 256)))) (pass-if (not (equal? (ash 1 256) -inf.0))) (pass-if (not (equal? -inf.0 (ash 1 256)))) ;; in gmp prior to 4.2, mpz_cmp_d ended up treating Inf as 2^1024, make ;; sure we've avoided that (pass-if (not (equal? (ash 1 1024) +inf.0))) (pass-if (not (equal? +inf.0 (ash 1 1024)))) (pass-if (not (equal? (- (ash 1 1024)) -inf.0))) (pass-if (not (equal? -inf.0 (- (ash 1 1024))))) (pass-if (not (equal? +nan.0 +nan.0))) (pass-if (not (equal? 0 +nan.0))) (pass-if (not (equal? +nan.0 0))) (pass-if (not (equal? 1 +nan.0))) (pass-if (not (equal? +nan.0 1))) (pass-if (not (equal? -1 +nan.0))) (pass-if (not (equal? +nan.0 -1))) (pass-if (not (equal? (ash 1 256) +nan.0))) (pass-if (not (equal? +nan.0 (ash 1 256)))) (pass-if (not (equal? (- (ash 1 256)) +nan.0))) (pass-if (not (equal? +nan.0 (- (ash 1 256))))) (pass-if (not (equal? (ash 1 8192) +nan.0))) (pass-if (not (equal? +nan.0 (ash 1 8192)))) (pass-if (not (equal? (- (ash 1 8192)) +nan.0))) (pass-if (not (equal? +nan.0 (- (ash 1 8192))))) ;; in gmp prior to 4.2, mpz_cmp_d ended up treating NaN as 3*2^1023, make ;; sure we've avoided that (pass-if (not (equal? (ash 3 1023) +nan.0))) (pass-if (not (equal? +nan.0 (ash 3 1023))))) ;;; ;;; = ;;; (with-test-prefix "=" (expect-fail (documented? =)) (pass-if (= 0 0)) (pass-if (= 7 7)) (pass-if (= -7 -7)) (pass-if (= (+ 1 fixnum-max) (+ 1 fixnum-max))) (pass-if (= (- fixnum-min 1) (- fixnum-min 1))) (pass-if (not (= 0 1))) (pass-if (not (= fixnum-max (+ 1 fixnum-max)))) (pass-if (not (= (+ 1 fixnum-max) fixnum-max))) (pass-if (not (= (+ 1 fixnum-max) (+ 2 fixnum-max)))) (pass-if (not (= fixnum-min (- fixnum-min 1)))) (pass-if (not (= (- fixnum-min 1) fixnum-min))) (pass-if (not (= (- fixnum-min 1) (- fixnum-min 2)))) (pass-if (not (= (+ fixnum-max 1) (- fixnum-min 1)))) (pass-if (not (= (ash 1 256) +inf.0))) (pass-if (not (= +inf.0 (ash 1 256)))) (pass-if (not (= (ash 1 256) -inf.0))) (pass-if (not (= -inf.0 (ash 1 256)))) ;; in gmp prior to 4.2, mpz_cmp_d ended up treating Inf as 2^1024, make ;; sure we've avoided that (pass-if (not (= (ash 1 1024) +inf.0))) (pass-if (not (= +inf.0 (ash 1 1024)))) (pass-if (not (= (- (ash 1 1024)) -inf.0))) (pass-if (not (= -inf.0 (- (ash 1 1024))))) (pass-if (not (= +nan.0 +nan.0))) (pass-if (not (= 0 +nan.0))) (pass-if (not (= +nan.0 0))) (pass-if (not (= 1 +nan.0))) (pass-if (not (= +nan.0 1))) (pass-if (not (= -1 +nan.0))) (pass-if (not (= +nan.0 -1))) (pass-if (not (= (ash 1 256) +nan.0))) (pass-if (not (= +nan.0 (ash 1 256)))) (pass-if (not (= (- (ash 1 256)) +nan.0))) (pass-if (not (= +nan.0 (- (ash 1 256))))) (pass-if (not (= (ash 1 8192) +nan.0))) (pass-if (not (= +nan.0 (ash 1 8192)))) (pass-if (not (= (- (ash 1 8192)) +nan.0))) (pass-if (not (= +nan.0 (- (ash 1 8192))))) ;; in gmp prior to 4.2, mpz_cmp_d ended up treating NaN as 3*2^1023, make ;; sure we've avoided that (pass-if (not (= (ash 3 1023) +nan.0))) (pass-if (not (= +nan.0 (ash 3 1023))))) ;;; ;;; < ;;; (with-test-prefix "<" (expect-fail "documented?" (documented? <)) (with-test-prefix "(< 0 n)" (pass-if "n = 0" (not (< 0 0))) (pass-if "n = 0.0" (not (< 0 0.0))) (pass-if "n = 1" (< 0 1)) (pass-if "n = 1.0" (< 0 1.0)) (pass-if "n = -1" (not (< 0 -1))) (pass-if "n = -1.0" (not (< 0 -1.0))) (pass-if "n = fixnum-max" (< 0 fixnum-max)) (pass-if "n = fixnum-max + 1" (< 0 (+ fixnum-max 1))) (pass-if "n = fixnum-min" (not (< 0 fixnum-min))) (pass-if "n = fixnum-min - 1" (not (< 0 (- fixnum-min 1))))) (with-test-prefix "(< 0.0 n)" (pass-if "n = 0" (not (< 0.0 0))) (pass-if "n = 0.0" (not (< 0.0 0.0))) (pass-if "n = 1" (< 0.0 1)) (pass-if "n = 1.0" (< 0.0 1.0)) (pass-if "n = -1" (not (< 0.0 -1))) (pass-if "n = -1.0" (not (< 0.0 -1.0))) (pass-if "n = fixnum-max" (< 0.0 fixnum-max)) (pass-if "n = fixnum-max + 1" (< 0.0 (+ fixnum-max 1))) (pass-if "n = fixnum-min" (not (< 0.0 fixnum-min))) (pass-if "n = fixnum-min - 1" (not (< 0.0 (- fixnum-min 1))))) (with-test-prefix "(< 1 n)" (pass-if "n = 0" (not (< 1 0))) (pass-if "n = 0.0" (not (< 1 0.0))) (pass-if "n = 1" (not (< 1 1))) (pass-if "n = 1.0" (not (< 1 1.0))) (pass-if "n = -1" (not (< 1 -1))) (pass-if "n = -1.0" (not (< 1 -1.0))) (pass-if "n = fixnum-max" (< 1 fixnum-max)) (pass-if "n = fixnum-max + 1" (< 1 (+ fixnum-max 1))) (pass-if "n = fixnum-min" (not (< 1 fixnum-min))) (pass-if "n = fixnum-min - 1" (not (< 1 (- fixnum-min 1))))) (with-test-prefix "(< 1.0 n)" (pass-if "n = 0" (not (< 1.0 0))) (pass-if "n = 0.0" (not (< 1.0 0.0))) (pass-if "n = 1" (not (< 1.0 1))) (pass-if "n = 1.0" (not (< 1.0 1.0))) (pass-if "n = -1" (not (< 1.0 -1))) (pass-if "n = -1.0" (not (< 1.0 -1.0))) (pass-if "n = fixnum-max" (< 1.0 fixnum-max)) (pass-if "n = fixnum-max + 1" (< 1.0 (+ fixnum-max 1))) (pass-if "n = fixnum-min" (not (< 1.0 fixnum-min))) (pass-if "n = fixnum-min - 1" (not (< 1.0 (- fixnum-min 1))))) (with-test-prefix "(< -1 n)" (pass-if "n = 0" (< -1 0)) (pass-if "n = 0.0" (< -1 0.0)) (pass-if "n = 1" (< -1 1)) (pass-if "n = 1.0" (< -1 1.0)) (pass-if "n = -1" (not (< -1 -1))) (pass-if "n = -1.0" (not (< -1 -1.0))) (pass-if "n = fixnum-max" (< -1 fixnum-max)) (pass-if "n = fixnum-max + 1" (< -1 (+ fixnum-max 1))) (pass-if "n = fixnum-min" (not (< -1 fixnum-min))) (pass-if "n = fixnum-min - 1" (not (< -1 (- fixnum-min 1))))) (with-test-prefix "(< -1.0 n)" (pass-if "n = 0" (< -1.0 0)) (pass-if "n = 0.0" (< -1.0 0.0)) (pass-if "n = 1" (< -1.0 1)) (pass-if "n = 1.0" (< -1.0 1.0)) (pass-if "n = -1" (not (< -1.0 -1))) (pass-if "n = -1.0" (not (< -1.0 -1.0))) (pass-if "n = fixnum-max" (< -1.0 fixnum-max)) (pass-if "n = fixnum-max + 1" (< -1.0 (+ fixnum-max 1))) (pass-if "n = fixnum-min" (not (< -1.0 fixnum-min))) (pass-if "n = fixnum-min - 1" (not (< -1.0 (- fixnum-min 1))))) (with-test-prefix "(< fixnum-max n)" (pass-if "n = 0" (not (< fixnum-max 0))) (pass-if "n = 0.0" (not (< fixnum-max 0.0))) (pass-if "n = 1" (not (< fixnum-max 1))) (pass-if "n = 1.0" (not (< fixnum-max 1.0))) (pass-if "n = -1" (not (< fixnum-max -1))) (pass-if "n = -1.0" (not (< fixnum-max -1.0))) (pass-if "n = fixnum-max" (not (< fixnum-max fixnum-max))) (pass-if "n = fixnum-max + 1" (< fixnum-max (+ fixnum-max 1))) (pass-if "n = fixnum-min" (not (< fixnum-max fixnum-min))) (pass-if "n = fixnum-min - 1" (not (< fixnum-max (- fixnum-min 1))))) (with-test-prefix "(< (+ fixnum-max 1) n)" (pass-if "n = 0" (not (< (+ fixnum-max 1) 0))) (pass-if "n = 0.0" (not (< (+ fixnum-max 1) 0.0))) (pass-if "n = 1" (not (< (+ fixnum-max 1) 1))) (pass-if "n = 1.0" (not (< (+ fixnum-max 1) 1.0))) (pass-if "n = -1" (not (< (+ fixnum-max 1) -1))) (pass-if "n = -1.0" (not (< (+ fixnum-max 1) -1.0))) (pass-if "n = fixnum-max" (not (< (+ fixnum-max 1) fixnum-max))) (pass-if "n = fixnum-max + 1" (not (< (+ fixnum-max 1) (+ fixnum-max 1)))) (pass-if "n = fixnum-min" (not (< (+ fixnum-max 1) fixnum-min))) (pass-if "n = fixnum-min - 1" (not (< (+ fixnum-max 1) (- fixnum-min 1))))) (with-test-prefix "(< fixnum-min n)" (pass-if "n = 0" (< fixnum-min 0)) (pass-if "n = 0.0" (< fixnum-min 0.0)) (pass-if "n = 1" (< fixnum-min 1)) (pass-if "n = 1.0" (< fixnum-min 1.0)) (pass-if "n = -1" (< fixnum-min -1)) (pass-if "n = -1.0" (< fixnum-min -1.0)) (pass-if "n = fixnum-max" (< fixnum-min fixnum-max)) (pass-if "n = fixnum-max + 1" (< fixnum-min (+ fixnum-max 1))) (pass-if "n = fixnum-min" (not (< fixnum-min fixnum-min))) (pass-if "n = fixnum-min - 1" (not (< fixnum-min (- fixnum-min 1))))) (with-test-prefix "(< (- fixnum-min 1) n)" (pass-if "n = 0" (< (- fixnum-min 1) 0)) (pass-if "n = 0.0" (< (- fixnum-min 1) 0.0)) (pass-if "n = 1" (< (- fixnum-min 1) 1)) (pass-if "n = 1.0" (< (- fixnum-min 1) 1.0)) (pass-if "n = -1" (< (- fixnum-min 1) -1)) (pass-if "n = -1.0" (< (- fixnum-min 1) -1.0)) (pass-if "n = fixnum-max" (< (- fixnum-min 1) fixnum-max)) (pass-if "n = fixnum-max + 1" (< (- fixnum-min 1) (+ fixnum-max 1))) (pass-if "n = fixnum-min" (< (- fixnum-min 1) fixnum-min)) (pass-if "n = fixnum-min - 1" (not (< (- fixnum-min 1) (- fixnum-min 1))))) (pass-if (< (ash 1 256) +inf.0)) (pass-if (not (< +inf.0 (ash 1 256)))) (pass-if (not (< (ash 1 256) -inf.0))) (pass-if (< -inf.0 (ash 1 256))) ;; in gmp prior to 4.2, mpz_cmp_d ended up treating Inf as 2^1024, make ;; sure we've avoided that (pass-if (< (1- (ash 1 1024)) +inf.0)) (pass-if (< (ash 1 1024) +inf.0)) (pass-if (< (1+ (ash 1 1024)) +inf.0)) (pass-if (not (< +inf.0 (1- (ash 1 1024))))) (pass-if (not (< +inf.0 (ash 1 1024)))) (pass-if (not (< +inf.0 (1+ (ash 1 1024))))) (pass-if (< -inf.0 (- (1- (ash 1 1024))))) (pass-if (< -inf.0 (- (ash 1 1024)))) (pass-if (< -inf.0 (- (1+ (ash 1 1024))))) (pass-if (not (< (- (1- (ash 1 1024))) -inf.0))) (pass-if (not (< (- (ash 1 1024)) -inf.0))) (pass-if (not (< (- (1+ (ash 1 1024))) -inf.0))) (pass-if (not (< +nan.0 +nan.0))) (pass-if (not (< 0 +nan.0))) (pass-if (not (< +nan.0 0))) (pass-if (not (< 1 +nan.0))) (pass-if (not (< +nan.0 1))) (pass-if (not (< -1 +nan.0))) (pass-if (not (< +nan.0 -1))) (pass-if (not (< (ash 1 256) +nan.0))) (pass-if (not (< +nan.0 (ash 1 256)))) (pass-if (not (< (- (ash 1 256)) +nan.0))) (pass-if (not (< +nan.0 (- (ash 1 256))))) (pass-if (not (< (ash 1 8192) +nan.0))) (pass-if (not (< +nan.0 (ash 1 8192)))) (pass-if (not (< (- (ash 1 8192)) +nan.0))) (pass-if (not (< +nan.0 (- (ash 1 8192))))) ;; in gmp prior to 4.2, mpz_cmp_d ended up treating NaN as 3*2^1023, make ;; sure we've avoided that (pass-if (not (< (ash 3 1023) +nan.0))) (pass-if (not (< (1+ (ash 3 1023)) +nan.0))) (pass-if (not (< (1- (ash 3 1023)) +nan.0))) (pass-if (not (< +nan.0 (ash 3 1023)))) (pass-if (not (< +nan.0 (1+ (ash 3 1023))))) (pass-if (not (< +nan.0 (1- (ash 3 1023)))))) ;;; ;;; > ;;; ;; currently not tested -- implementation is trivial ;; (> x y) is implemented as (< y x) ;; FIXME: tests should probably be added in case we change implementation. ;;; ;;; <= ;;; ;; currently not tested -- implementation is trivial ;; (<= x y) is implemented as (not (< y x)) ;; FIXME: tests should probably be added in case we change implementation. ;;; ;;; >= ;;; ;; currently not tested -- implementation is trivial ;; (>= x y) is implemented as (not (< x y)) ;; FIXME: tests should probably be added in case we change implementation. ;;; ;;; zero? ;;; (with-test-prefix "zero?" (expect-fail (documented? zero?)) (pass-if (zero? 0)) (pass-if (not (zero? 7))) (pass-if (not (zero? -7))) (pass-if (not (zero? (+ 1 fixnum-max)))) (pass-if (not (zero? (- 1 fixnum-min)))) (pass-if (not (zero? 1.3))) (pass-if (not (zero? 3.1+4.2i)))) ;;; ;;; positive? ;;; (with-test-prefix "positive?" (expect-fail (documented? positive?)) (pass-if (positive? 1)) (pass-if (positive? (+ fixnum-max 1))) (pass-if (positive? 1.3)) (pass-if (not (positive? 0))) (pass-if (not (positive? -1))) (pass-if (not (positive? (- fixnum-min 1)))) (pass-if (not (positive? -1.3)))) ;;; ;;; negative? ;;; (with-test-prefix "negative?" (expect-fail (documented? negative?)) (pass-if (not (negative? 1))) (pass-if (not (negative? (+ fixnum-max 1)))) (pass-if (not (negative? 1.3))) (pass-if (not (negative? 0))) (pass-if (negative? -1)) (pass-if (negative? (- fixnum-min 1))) (pass-if (negative? -1.3))) ;;; ;;; max ;;; (with-test-prefix "max" (pass-if (= 456.0 (max 123.0 456.0))) (pass-if (= 456.0 (max 456.0 123.0))) (let ((big*2 (* fixnum-max 2)) (big*3 (* fixnum-max 3)) (big*4 (* fixnum-max 4)) (big*5 (* fixnum-max 5))) (pass-if (= +inf.0 (max big*5 +inf.0))) (pass-if (= +inf.0 (max +inf.0 big*5))) (pass-if (= big*5 (max big*5 -inf.0))) (pass-if (= big*5 (max -inf.0 big*5))) (pass-if (nan? (max 123 +nan.0))) (pass-if (nan? (max big*5 +nan.0))) (pass-if (nan? (max 123.0 +nan.0))) (pass-if (nan? (max +nan.0 123))) (pass-if (nan? (max +nan.0 big*5))) (pass-if (nan? (max +nan.0 123.0))) (pass-if (nan? (max +nan.0 +nan.0)))) ;; in gmp prior to 4.2, mpz_cmp_d ended up treating Inf as 2^1024, make ;; sure we've avoided that (for-each (lambda (b) (pass-if (list b +inf.0) (= +inf.0 (max b +inf.0))) (pass-if (list +inf.0 b) (= +inf.0 (max b +inf.0))) (pass-if (list b -inf.0) (= b (max b -inf.0))) (pass-if (list -inf.0 b) (= b (max b -inf.0)))) (list (1- (ash 1 1024)) (ash 1 1024) (1+ (ash 1 1024)) (- (1- (ash 1 1024))) (- (ash 1 1024)) (- (1+ (ash 1 1024))))) ;; in gmp prior to 4.2, mpz_cmp_d ended up treating NaN as 3*2^1023, make ;; sure we've avoided that (pass-if (nan? (max (ash 1 2048) +nan.0))) (pass-if (nan? (max +nan.0 (ash 1 2048))))) ;;; ;;; min ;;; ;; FIXME: unfinished... (with-test-prefix "min" (pass-if (= 123.0 (min 123.0 456.0))) (pass-if (= 123.0 (min 456.0 123.0))) (let ((big*2 (* fixnum-max 2)) (big*3 (* fixnum-max 3)) (big*4 (* fixnum-max 4)) (big*5 (* fixnum-max 5))) (expect-fail (documented? max)) (pass-if (= 1 (min 7 3 1 5))) (pass-if (= 1 (min 1 7 3 5))) (pass-if (= 1 (min 7 3 5 1))) (pass-if (= -7 (min 2 3 4 -2 5 -7 1 -1 4 2))) (pass-if (= -7 (min -7 2 3 4 -2 5 1 -1 4 2))) (pass-if (= -7 (min 2 3 4 -2 5 1 -1 4 2 -7))) (pass-if (= big*2 (min big*3 big*5 big*2 big*4))) (pass-if (= big*2 (min big*2 big*3 big*5 big*4))) (pass-if (= big*2 (min big*3 big*5 big*4 big*2))) (pass-if (= (- fixnum-min 1) (min 2 4 (- fixnum-min 1) 3 (* 2 fixnum-max)))) (pass-if (= (- fixnum-min 1) (min (- fixnum-min 1) 2 4 3 (* 2 fixnum-max)))) (pass-if (= (- fixnum-min 1) (min 2 4 3 (* 2 fixnum-max) (- fixnum-min 1)))) (pass-if (= big*5 (min big*5 +inf.0))) (pass-if (= big*5 (min +inf.0 big*5))) (pass-if (= -inf.0 (min big*5 -inf.0))) (pass-if (= -inf.0 (min -inf.0 big*5))) (pass-if (nan? (min 123 +nan.0))) (pass-if (nan? (min big*5 +nan.0))) (pass-if (nan? (min 123.0 +nan.0))) (pass-if (nan? (min +nan.0 123))) (pass-if (nan? (min +nan.0 big*5))) (pass-if (nan? (min +nan.0 123.0))) (pass-if (nan? (min +nan.0 +nan.0)))) ;; in gmp prior to 4.2, mpz_cmp_d ended up treating Inf as 2^1024, make ;; sure we've avoided that (for-each (lambda (b) (pass-if (list b +inf.0) (= b (min b +inf.0))) (pass-if (list +inf.0 b) (= b (min b +inf.0))) (pass-if (list b -inf.0) (= -inf.0 (min b -inf.0))) (pass-if (list -inf.0 b) (= -inf.0 (min b -inf.0)))) (list (1- (ash 1 1024)) (ash 1 1024) (1+ (ash 1 1024)) (- (1- (ash 1 1024))) (- (ash 1 1024)) (- (1+ (ash 1 1024))))) ;; in gmp prior to 4.2, mpz_cmp_d ended up treating NaN as 3*2^1023, make ;; sure we've avoided that (pass-if (nan? (min (- (ash 1 2048)) (- +nan.0)))) (pass-if (nan? (min (- +nan.0) (- (ash 1 2048)))))) ;;; ;;; + ;;; (with-test-prefix "+" (expect-fail "documented?" (documented? +)) (with-test-prefix "wrong type argument" (pass-if-exception "1st argument string" exception:wrong-type-arg (+ "1" 2)) (pass-if-exception "2nd argument bool" exception:wrong-type-arg (+ 1 #f)))) ;;; ;;; - ;;; (with-test-prefix "-" (pass-if "-inum - +bignum" (= #x-100000000000000000000000000000001 (- -1 #x100000000000000000000000000000000))) (pass-if "big - inum" (= #xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF (- #x100000000000000000000000000000000 1))) (pass-if "big - -inum" (= #x100000000000000000000000000000001 (- #x100000000000000000000000000000000 -1)))) ;;; ;;; * ;;; (with-test-prefix "*" (pass-if "complex * bignum" (let ((big (ash 1 90))) (= (make-rectangular big big) (* 1+1i big))))) ;;; ;;; / ;;; (with-test-prefix "/" (expect-fail "documented?" (documented? /)) (with-test-prefix "division by zero" (pass-if-exception "(/ 0)" exception:numerical-overflow (/ 0)) (pass-if "(/ 0.0)" (= +inf.0 (/ 0.0))) (pass-if-exception "(/ 1 0)" exception:numerical-overflow (/ 1 0)) (pass-if "(/ 1 0.0)" (= +inf.0 (/ 1 0.0))) (pass-if-exception "(/ bignum 0)" exception:numerical-overflow (/ (+ fixnum-max 1) 0)) (pass-if "(/ bignum 0.0)" (= +inf.0 (/ (+ fixnum-max 1) 0.0))) (pass-if-exception "(/ 1.0 0)" exception:numerical-overflow (/ 1.0 0)) (pass-if "(/ 1.0 0.0)" (= +inf.0 (/ 1.0 0.0))) (pass-if-exception "(/ +i 0)" exception:numerical-overflow (/ +i 0)) (pass-if "(/ +i 0.0)" (= +inf.0 (imag-part (/ +i 0.0))))) (with-test-prefix "complex division" (pass-if "(/ 3+4i)" (= (/ 3+4i) 0.12-0.16i)) (pass-if "(/ 4+3i)" (= (/ 4+3i) 0.16-0.12i)) (pass-if "(/ 25+125i 3+4i)" (= (/ 25+125i 3+4i) 23.0+11.0i)) (pass-if "(/ 25+125i 4+3i)" (= (/ 25+125i 4+3i) 19.0+17.0i)) (pass-if "(/ 25 3+4i)" (= (/ 25 3+4i) 3.0-4.0i)) (pass-if "(/ 25 4+3i)" (= (/ 25 4+3i) 4.0-3.0i)) (pass-if "(/ 1e200+1e200i)" (= (/ 1e200+1e200i) 5.0e-201-5.0e-201i)))) ;;; ;;; truncate ;;; (with-test-prefix "truncate" (pass-if (= 1 (truncate 1.75))) (pass-if (= 1 (truncate 1.5))) (pass-if (= 1 (truncate 1.25))) (pass-if (= 0 (truncate 0.75))) (pass-if (= 0 (truncate 0.5))) (pass-if (= 0 (truncate 0.0))) (pass-if (= 0 (truncate -0.5))) (pass-if (= -1 (truncate -1.25))) (pass-if (= -1 (truncate -1.5)))) ;;; ;;; round ;;; (with-test-prefix "round" (pass-if (= 2 (round 1.75))) (pass-if (= 2 (round 1.5))) (pass-if (= 1 (round 1.25))) (pass-if (= 1 (round 0.75))) (pass-if (= 0 (round 0.5))) (pass-if (= 0 (round 0.0))) (pass-if (= 0 (round -0.5))) (pass-if (= -1 (round -1.25))) (pass-if (= -2 (round -1.5)))) ;;; ;;; exact->inexact ;;; (with-test-prefix "exact->inexact" ;; Test "(exact->inexact n)", expect "want". ;; "i" is a index, for diagnostic purposes. (define (try-i i n want) (with-test-prefix (list i n want) (with-test-prefix "pos" (let ((got (exact->inexact n))) (pass-if "inexact?" (inexact? got)) (pass-if (list "=" got) (= want got)))) (set! n (- n)) (set! want (- want)) (with-test-prefix "neg" (let ((got (exact->inexact n))) (pass-if "inexact?" (inexact? got)) (pass-if (list "=" got) (= want got)))))) (with-test-prefix "2^i, no round" (do ((i 0 (1+ i)) (n 1 (* 2 n)) (want 1.0 (* 2.0 want))) ((> i 100)) (try-i i n want))) (with-test-prefix "2^i+1, no round" (do ((i 1 (1+ i)) (n 3 (1- (* 2 n))) (want 3.0 (- (* 2.0 want) 1.0))) ((>= i dbl-mant-dig)) (try-i i n want))) (with-test-prefix "(2^i+1)*2^100, no round" (do ((i 1 (1+ i)) (n 3 (1- (* 2 n))) (want 3.0 (- (* 2.0 want) 1.0))) ((>= i dbl-mant-dig)) (try-i i (ash n 100) (ash-flo want 100)))) ;; bit pattern: 1111....11100.00 ;; <-mantdig-><-i-> ;; (with-test-prefix "mantdig ones then zeros, no rounding" (do ((i 0 (1+ i)) (n (- (ash 1 dbl-mant-dig) 1) (* 2 n)) (want (- (ash-flo 1.0 dbl-mant-dig) 1.0) (* 2.0 want))) ((> i 100)) (try-i i n want))) ;; bit pattern: 1111....111011..1 ;; <-mantdig-> <-i-> ;; This sort of value was incorrectly rounded upwards in Guile 1.6.4 when ;; i >= 11 (that's when the total is 65 or more bits). ;; (with-test-prefix "mantdig ones then 011..11, round down" (do ((i 0 (1+ i)) (n (- (ash 1 (+ 1 dbl-mant-dig)) 2) (+ 1 (* 2 n))) (want (- (ash-flo 1.0 (+ 1 dbl-mant-dig)) 2.0) (* 2.0 want))) ((> i 100)) (try-i i n want))) ;; bit pattern: 1111....111100..001 ;; <-mantdig-> <--i-> ;; (with-test-prefix "mantdig ones then 100..001, round up" (do ((i 0 (1+ i)) (n (- (ash 1 (+ 2 dbl-mant-dig)) 1) (1- (* 2 n))) (want (ash-flo 1.0 (+ 2 dbl-mant-dig)) (* 2.0 want))) ((> i 100)) (try-i i n want))) ;; bit pattern: 1000....000100..001 ;; <-mantdig-> <--i-> ;; (with-test-prefix "2^mantdig then 100..001, round up" (do ((i 0 (1+ i)) (n (- (ash 1 (+ 2 dbl-mant-dig)) 1) (1- (* 2 n))) (want (+ (ash-flo 1.0 (+ 2 dbl-mant-dig)) 4.0) (* 2.0 want))) ((> i 100)) (try-i i n want)))) ;;; ;;; floor ;;; ;;; ;;; ceiling ;;; ;;; ;;; expt ;;; (with-test-prefix "expt" (pass-if "(= 1 (expt 0 0))" (= 1 (expt 0 0))) (pass-if "(= 1 (expt 0 0.0))" (= 1 (expt 0 0.0))) (pass-if "(= 1 (expt 0.0 0))" (= 1 (expt 0.0 0))) (pass-if "(= 1 (expt 0.0 0.0))" (= 1 (expt 0.0 0.0)))) ;;; ;;; asinh ;;; (with-test-prefix "asinh" (pass-if (= 0 (asinh 0)))) ;;; ;;; acosh ;;; (with-test-prefix "acosh" (pass-if (= 0 (acosh 1)))) ;;; ;;; atanh ;;; (with-test-prefix "atanh" (pass-if (= 0 (atanh 0)))) ;;; ;;; make-rectangular ;;; ;;; ;;; make-polar ;;; (with-test-prefix "make-polar" (define pi 3.14159265358979323846) (define (almost= x y) (> 0.01 (magnitude (- x y)))) (pass-if (= 0 (make-polar 0 0))) (pass-if (= 0 (make-polar 0 123.456))) (pass-if (= 1 (make-polar 1 0))) (pass-if (= -1 (make-polar -1 0))) (pass-if (almost= 0+i (make-polar 1 (* 0.5 pi)))) (pass-if (almost= -1 (make-polar 1 (* 1.0 pi)))) (pass-if (almost= 0-i (make-polar 1 (* 1.5 pi)))) (pass-if (almost= 1 (make-polar 1 (* 2.0 pi))))) ;;; ;;; real-part ;;; ;;; ;;; imag-part ;;; ;;; ;;; magnitude ;;; (with-test-prefix "magnitude" (pass-if (= 0 (magnitude 0))) (pass-if (= 1 (magnitude 1))) (pass-if (= 1 (magnitude -1))) (pass-if (= 1 (magnitude 0+i))) (pass-if (= 1 (magnitude 0-i))) (pass-if (= 5 (magnitude 3+4i))) (pass-if (= 5 (magnitude 3-4i))) (pass-if (= 5 (magnitude -3+4i))) (pass-if (= 5 (magnitude -3-4i)))) ;;; ;;; angle ;;; (with-test-prefix "angle" (define pi 3.14159265358979323846) (define (almost= x y) (> 0.01 (magnitude (- x y)))) (pass-if "inum +ve" (= 0 (angle 1))) (pass-if "inum -ve" (almost= pi (angle -1))) (pass-if "bignum +ve" (= 0 (angle (1+ fixnum-max)))) (pass-if "bignum -ve" (almost= pi (angle (1- fixnum-min)))) (pass-if "flonum +ve" (= 0 (angle 1.5))) (pass-if "flonum -ve" (almost= pi (angle -1.5)))) ;;; ;;; inexact->exact ;;; (with-test-prefix "inexact->exact" (pass-if-exception "+inf" exception:out-of-range (inexact->exact +inf.0)) (pass-if-exception "-inf" exception:out-of-range (inexact->exact -inf.0)) (pass-if-exception "nan" exception:out-of-range (inexact->exact +nan.0)) (with-test-prefix "2.0**i to exact and back" (do ((i 0 (1+ i)) (n 1.0 (* 2.0 n))) ((> i 100)) (pass-if (list i n) (= n (inexact->exact (exact->inexact n))))))) ;;; ;;; integer-length ;;; (with-test-prefix "integer-length" (with-test-prefix "-2^i, ...11100..00" (do ((n -1 (ash n 1)) (i 0 (1+ i))) ((> i 256)) (pass-if (list n "expect" i) (= i (integer-length n))))) (with-test-prefix "-2^i+1 ...11100..01" (do ((n -3 (logxor 3 (ash n 1))) (i 2 (1+ i))) ((> i 256)) (pass-if n (= i (integer-length n))))) (with-test-prefix "-2^i-1 ...111011..11" (do ((n -2 (1+ (ash n 1))) (i 1 (1+ i))) ((> i 256)) (pass-if n (= i (integer-length n)))))) ;;; ;;; logcount ;;; (with-test-prefix "logcount" (with-test-prefix "-2^i, meaning ...11100..00" (do ((n -1 (ash n 1)) (i 0 (1+ i))) ((> i 256)) (pass-if n (= i (logcount n))))) (with-test-prefix "2^i" (do ((n 1 (ash n 1)) (i 0 (1+ i))) ((> i 256)) (pass-if n (= 1 (logcount n))))) (with-test-prefix "2^i-1" (do ((n 0 (1+ (ash n 1))) (i 0 (1+ i))) ((> i 256)) (pass-if n (= i (logcount n)))))) ;;; ;;; lognot ;;; (with-test-prefix "lognot" (pass-if (= -1 (lognot 0))) (pass-if (= 0 (lognot -1))) (pass-if (= -2 (lognot 1))) (pass-if (= 1 (lognot -2))) (pass-if (= #x-100000000000000000000000000000000 (lognot #xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF))) (pass-if (= #xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF (lognot #x-100000000000000000000000000000000))))