;;;; numbers.types - Hand-coded type-information for "numbers" -*- Scheme -*- ;; Any type of number: ;; ;; (or fixnum float number (struct bignum) (struct ratnum) (struct compnum)) ;; ;; Note that the "number" type is a builtin Chicken type representing ;; "fixnum or float", however it is disjoint from either! It doesn't match ;; any of the "numbers" egg types. (numbers#eqv? (#(procedure #:pure) numbers#eqv? (* *) boolean) ((immediate *) (eq? #(1) #(2))) ((* immediate) (eq? #(1) #(2)))) (numbers#equal? (#(procedure #:pure) numbers#equal? (* *) boolean) ((immediate *) (eq? #(1) #(2))) ((* immediate) (eq? #(1) #(2)))) (numbers#equal=? (#(procedure #:clean) numbers#equal=? (* *) boolean) ((immediate *) (eq? #(1) #(2))) ((* immediate) (eq? #(1) #(2))) (((or float number (struct bignum) (struct ratnum) (struct compnum)) (or float number (struct bignum) (struct ratnum) (struct compnum))) (numbers#= #(1) #(2)))) (numbers#number? (#(procedure #:pure) numbers#number? (*) boolean) (((or fixnum float number (struct bignum) (struct ratnum) (struct compnum))) (let ((#(tmp) #(1))) '#t))) (numbers#integer? (#(procedure #:pure) numbers#integer? (*) boolean) (((or fixnum (struct bignum))) (let ((#(tmp) #(1))) '#t)) ((float) (##core#inline "C_u_i_fpintegerp" #(1)))) (numbers#exact-integer? (#(procedure #:pure) numbers#exact-integer? (*) boolean) (((or fixnum (struct bignum))) (let ((#(tmp) #(1))) '#t)) (((not (or fixnum (struct bignum)))) (let ((#(tmp) #(1))) '#f))) (numbers#exact? (#(procedure #:pure #:enforce) numbers#exact? ((or fixnum float number (struct bignum) (struct ratnum) (struct compnum))) boolean) (((or fixnum (struct bignum) (struct ratnum))) (let ((#(tmp) #(1))) '#t)) ((float) (let ((#(tmp) #(1))) '#f))) (numbers#inexact? (#(procedure #:pure #:enforce) numbers#inexact? ((or fixnum float number (struct bignum) (struct ratnum) (struct compnum))) boolean) (((or fixnum (struct bignum) (struct ratnum))) (let ((#(tmp) #(1))) '#f)) ((float) (let ((#(tmp) #(1))) '#t))) (numbers#real? (#(procedure #:pure) numbers#real? (*) boolean)) ;XXX add specializations? (numbers#complex? (#(procedure #:pure) numbers#complex? (*) boolean) (((struct compnum)) (let ((#(tmp) #(1))) '#t))) (numbers#rational? (#(procedure #:pure) numbers#rational? (*) boolean) ((fixnum) (let ((#(tmp) #(1))) '#t))) ;XXX more? (numbers#bignum? (#(procedure #:pure #:predicate (struct bignum)) numbers#bignum? (*) boolean)) (numbers#ratnum? (#(procedure #:pure #:predicate (struct ratnum)) numbers#ratnum? (*) boolean)) (numbers#cplxnum? (#(procedure #:pure #:predicate (struct compnum)) numbers#cplxnum? (*) boolean)) (numbers#nan? (#(procedure #:clean #:enforce) numbers#nan? ((or fixnum float number (struct bignum) (struct ratnum) (struct compnum))) boolean) (((or fixnum (struct bignum) (struct ratnum))) (let ((#(tmp) #(1))) '#f))) (numbers#infinite? (#(procedure #:clean #:enforce) numbers#infinite? ((or fixnum float number (struct bignum) (struct ratnum) (struct compnum))) boolean) (((or fixnum (struct bignum) (struct ratnum))) (let ((#(tmp) #(1))) '#f))) (numbers#finite? (#(procedure #:clean #:enforce) numbers#finite? ((or fixnum float number (struct bignum) (struct ratnum) (struct compnum))) boolean) (((or fixnum (struct bignum) (struct ratnum))) (let ((#(tmp) #(1))) '#t))) (numbers#rectnum? (#(procedure #:pure) numbers#rectnum? (*) boolean) (((or fixnum float number (struct bignum) (struct ratnum))) (let ((#(tmp) #(1))) '#f))) (numbers#compnum? (#(procedure #:pure) numbers#compnum? (*) boolean) (((or fixnum float number (struct bignum) (struct ratnum))) (let ((#(tmp) #(1))) '#f))) (numbers#cintnum? (#(procedure #:pure) numbers#cintnum? (*) boolean) (((or fixnum float number (struct bignum))) (let ((#(tmp) #(1))) '#t)) (((struct ratnum)) (let ((#(tmp) #(1))) '#f))) (numbers#cflonum? (#(procedure #:pure) numbers#cflonum? (*) boolean) ((float) (let ((#(tmp) #(1))) '#t)) (((or fixnum number (struct bignum) (struct ratnum))) (let ((#(tmp) #(1))) '#f))) (numbers#zero? (#(procedure #:clean #:enforce) numbers#zero? ((or fixnum float (struct bignum) (struct compnum) (struct ratnum))) boolean) ((fixnum) (eq? #(1) '0)) ((float) (##core#inline "C_u_i_zerop" #(1)))) (numbers#odd? (#(procedure #:clean) numbers#odd? (*) boolean) ((fixnum) (fxodd? #(1)))) (numbers#even? (#(procedure #:clean) numbers#even? (*) boolean) ((fixnum) (fxeven? #(1)))) (numbers#positive? (#(procedure #:clean #:enforce) numbers#positive? ((or fixnum float (struct bignum) (struct compnum) (struct ratnum))) boolean) ((fixnum) (##core#inline "C_fixnum_greaterp" #(1) '0)) ((float) (##core#inline "C_u_i_positivep" #(1)))) (numbers#negative? (#(procedure #:clean #:enforce) numbers#negative? ((or fixnum float (struct bignum) (struct compnum) (struct ratnum))) boolean) ((fixnum) (##core#inline "C_fixnum_lessp" #(1) '0)) ((float) (##core#inline "C_u_i_negativep" #(1)))) (numbers#max (#(procedure #:clean #:enforce) numbers#max (#!rest (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) ((fixnum fixnum) (fxmax #(1) #(2))) ((float float) (##core#inline "C_i_flonum_max" #(1) #(2)))) (numbers#min (#(procedure #:clean #:enforce) numbers#min (#!rest (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) ((fixnum fixnum) (fxmin #(1) #(2))) ((float float) (##core#inline "C_i_flonum_min" #(1) #(2)))) (numbers#+ (#(procedure #:clean #:enforce) numbers#+ (#!rest (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) ((float fixnum) (float) (##core#inline_allocate ("C_a_i_flonum_plus" 4) #(1) (##core#inline_allocate ("C_a_i_fix_to_flo" 4) #(2)))) ((fixnum float) (float) (##core#inline_allocate ("C_a_i_flonum_plus" 4) (##core#inline_allocate ("C_a_i_fix_to_flo" 4) #(1)) #(2))) ((float float) (float) (##core#inline_allocate ("C_a_i_flonum_plus" 4) #(1) #(2)))) (numbers#add1 (#(procedure #:clean #:enforce) numbers#add1 ((or fixnum float (struct bignum) (struct compnum) (struct ratnum))) (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) ((float) (float) (##core#inline_allocate ("C_a_i_flonum_plus" 4) #(1) '1.0))) (numbers#- (#(procedure #:clean #:enforce) numbers#- ((or fixnum float (struct bignum) (struct compnum) (struct ratnum)) #!rest (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) ;; This breaks when negating the smallest possible fixnum ;; (which negates to itself in 2s complement) #;((fixnum) (fixnum) (##core#inline "C_u_fixnum_negate" #(1))) ((float fixnum) (float) (##core#inline_allocate ("C_a_i_flonum_difference" 4) #(1) (##core#inline_allocate ("C_a_i_fix_to_flo" 4) #(2)))) ((fixnum float) (float) (##core#inline_allocate ("C_a_i_flonum_difference" 4) (##core#inline_allocate ("C_a_i_fix_to_flo" 4) #(1)) #(2))) ((float float) (float) (##core#inline_allocate ("C_a_i_flonum_difference" 4) #(1) #(2))) ((float) (float) (##core#inline_allocate ("C_a_i_flonum_negate" 4) #(1)))) (numbers#sub1 (#(procedure #:clean #:enforce) numbers#sub1 ((or fixnum float (struct bignum) (struct compnum) (struct ratnum))) (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) ((float) (float) (##core#inline_allocate ("C_a_i_flonum_difference" 4) #(1) '1.0))) (numbers#signum (#(procedure #:clean #:enforce) numbers#signum ((or fixnum float (struct bignum) (struct ratnum))) (or fixnum float))) (numbers#* (#(procedure #:clean #:enforce) numbers#* (#!rest (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) ((float fixnum) (float) (##core#inline_allocate ("C_a_i_flonum_times" 4) #(1) (##core#inline_allocate ("C_a_i_fix_to_flo" 4) #(2)))) ((fixnum float) (float) (##core#inline_allocate ("C_a_i_flonum_times" 4) (##core#inline_allocate ("C_a_i_fix_to_flo" 4) #(1)) #(2))) ((float float) (float) (##core#inline_allocate ("C_a_i_flonum_times" 4) #(1) #(2)))) (numbers#/ (#(procedure #:clean #:enforce) numbers#/ ((or fixnum float (struct bignum) (struct compnum) (struct ratnum)) #!rest (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) ((float fixnum) (float) (##core#inline_allocate ("C_a_i_flonum_quotient" 4) #(1) (##core#inline_allocate ("C_a_i_fix_to_flo" 4) #(2)))) ((fixnum float) (float) (##core#inline_allocate ("C_a_i_flonum_quotient" 4) (##core#inline_allocate ("C_a_i_fix_to_flo" 4) #(1)) #(2))) ((float float) (float) (##core#inline_allocate ("C_a_i_flonum_quotient" 4) #(1) #(2)))) (numbers#= (#(procedure #:clean #:enforce) numbers#= (#!rest (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) boolean) ((fixnum fixnum) (eq? #(1) #(2))) ;; These are incorrect on 64 bit-platforms (fixnums > 2^53) #;((float fixnum) (##core#inline "C_flonum_equalp" #(1) (##core#inline_allocate ("C_a_i_fix_to_flo" 4) #(2)))) #;((fixnum float) (##core#inline "C_flonum_equalp" (##core#inline_allocate ("C_a_i_fix_to_flo" 4) #(1)) #(2))) ((float float) (##core#inline "C_flonum_equalp" #(1) #(2)))) (numbers#> (#(procedure #:clean #:enforce) numbers#> (#!rest (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) boolean) ((fixnum fixnum) (fx> #(1) #(2))) ;; These are incorrect on 64 bit-platforms (fixnums > 2^53) #;((float fixnum) (##core#inline "C_flonum_greaterp" #(1) (##core#inline_allocate ("C_a_i_fix_to_flo" 4) #(2)))) #;((fixnum float) (##core#inline "C_flonum_greaterp" (##core#inline_allocate ("C_a_i_fix_to_flo" 4) #(1)) #(2))) ((float float) (##core#inline "C_flonum_greaterp" #(1) #(2)))) (numbers#< (#(procedure #:clean #:enforce) numbers#< (#!rest (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) boolean) ((fixnum fixnum) (fx< #(1) #(2))) ;; These are incorrect on 64 bit-platforms (fixnums > 2^53) #;((float fixnum) (##core#inline "C_flonum_lessp" #(1) (##core#inline_allocate ("C_a_i_fix_to_flo" 4) #(2)))) #;((fixnum float) (##core#inline "C_flonum_lessp" (##core#inline_allocate ("C_a_i_fix_to_flo" 4) #(1)) #(2))) ((float float) (##core#inline "C_flonum_lessp" #(1) #(2)))) (numbers#>= (#(procedure #:clean #:enforce) numbers#>= (#!rest (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) boolean) ((fixnum fixnum) (fx>= #(1) #(2))) ;; These are incorrect on 64 bit-platforms (fixnums > 2^53) #;((float fixnum) (##core#inline "C_flonum_greater_or_equal_p" #(1) (##core#inline_allocate ("C_a_i_fix_to_flo" 4) #(2)))) #;((fixnum float) (##core#inline "C_flonum_greater_or_equal_p" (##core#inline_allocate ("C_a_i_fix_to_flo" 4) #(1)) #(2))) ((float float) (##core#inline "C_flonum_greater_or_equal_p" #(1) #(2)))) (numbers#<= (#(procedure #:clean #:enforce) numbers#<= (#!rest (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) boolean) ((fixnum fixnum) (fx<= #(1) #(2))) ;; These are incorrect on 64 bit-platforms (fixnums > 2^53) #;((float fixnum) (##core#inline "C_flonum_less_or_equal_p" #(1) (##core#inline_allocate ("C_a_i_fix_to_flo" 4) #(2)))) #;((fixnum float) (##core#inline "C_flonum_less_or_equal_p" (##core#inline_allocate ("C_a_i_fix_to_flo" 4) #(1)) #(2))) ((float float) (##core#inline "C_flonum_less_or_equal_p" #(1) #(2)))) (numbers#quotient (#(procedure #:clean #:enforce) numbers#quotient ((or fixnum float (struct bignum) (struct compnum) (struct ratnum)) (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) ;;XXX flonum/mixed case ;;XXX is this correct? ((fixnum fixnum) (fixnum) (##core#inline "C_fixnum_divide" #(1) #(2)))) (numbers#remainder (#(procedure #:clean #:enforce) numbers#remainder ((or fixnum float (struct bignum) (struct compnum) (struct ratnum)) (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) ;;XXX flonum/mixed case ;;XXX is this correct? ((fixnum fixnum) (fixnum) (##core#inline "C_fixnum_modulo" #(1) #(2)))) (numbers#modulo (#(procedure #:clean #:enforce) numbers#modulo ((or fixnum float (struct bignum) (struct compnum) (struct ratnum)) (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) (or fixnum float (struct bignum) (struct compnum) (struct ratnum)))) (numbers#gcd (#(procedure #:clean #:enforce) numbers#gcd (#!rest (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) (or fixnum float (struct bignum) (struct compnum) (struct ratnum)))) (numbers#lcm (#(procedure #:clean #:enforce) numbers#lcm (#!rest (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) (or fixnum float (struct bignum) (struct compnum) (struct ratnum)))) (numbers#abs (#(procedure #:clean #:enforce) numbers#abs ((or fixnum float (struct bignum) (struct compnum) (struct ratnum))) (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) ((fixnum) (fixnum) (##core#inline "C_fixnum_abs" #(1))) ((float) (float) (##core#inline_allocate ("C_a_i_flonum_abs" 4) #(1)))) (numbers#floor (#(procedure #:clean #:enforce) numbers#floor ((or fixnum float (struct bignum) (struct compnum) (struct ratnum))) (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) ((fixnum) (fixnum) #(1)) ((float) (float) (##core#inline_allocate ("C_a_i_flonum_floor" 4) #(1)))) (numbers#ceiling (#(procedure #:clean #:enforce) numbers#ceiling ((or fixnum float (struct bignum) (struct compnum) (struct ratnum))) (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) ((fixnum) (fixnum) #(1)) ((float) (float) (##core#inline_allocate ("C_a_i_flonum_ceiling" 4) #(1)))) (numbers#truncate (#(procedure #:clean #:enforce) numbers#truncate ((or fixnum float (struct bignum) (struct ratnum))) (or fixnum float (struct bignum))) ((fixnum) (fixnum) #(1)) (((struct bignum)) ((struct bignum)) #(1)) ((float) (float) (##core#inline_allocate ("C_a_i_flonum_truncate" 4) #(1)))) (numbers#round (#(procedure #:clean #:enforce) numbers#round ((or fixnum float (struct bignum) (struct ratnum))) (or fixnum float (struct bignum))) ((fixnum) (fixnum) #(1)) (((struct bignum)) ((struct bignum)) #(1)) ((float) (float) (##core#inline_allocate ("C_a_i_flonum_round_proper" 4) #(1)))) (numbers#numerator (#(procedure #:clean #:enforce) numbers#numerator ((or fixnum float (struct bignum) (struct ratnum))) (or fixnum float (struct bignum))) (((struct bignum)) ((struct bignum)) #(1)) ((fixnum) (fixnum) #(1)) (((struct ratnum)) (##sys#slot #(1) '1))) (numbers#denominator (#(procedure #:clean #:enforce) numbers#denominator ((or fixnum float (struct bignum) (struct ratnum))) (or fixnum float (struct bignum))) (((or fixnum (struct bignum))) (fixnum) (let ((#(tmp) #(1))) '1)) (((struct ratnum)) (##sys#slot #(1) '2))) (numbers#exact->inexact (#(procedure #:clean #:enforce) numbers#exact->inexact ((or fixnum float (struct bignum) (struct compnum) (struct ratnum))) float) ((float) #(1)) ((fixnum) (##core#inline_allocate ("C_a_i_fix_to_flo" 4) #(1)))) (numbers#inexact->exact (#(procedure #:clean #:enforce) numbers#inexact->exact ((or fixnum float (struct bignum) (struct compnum) (struct ratnum))) fixnum) ;;XXX float case? ((fixnum) #(1))) (numbers#exp (#(procedure #:clean #:enforce) numbers#exp ((or fixnum float (struct bignum) (struct compnum) (struct ratnum))) (or float (struct compnum))) ((float) (float) (##core#inline_allocate ("C_a_i_flonum_exp" 4) #(1)))) (numbers#log (#(procedure #:clean #:enforce) numbers#log ((or fixnum float (struct bignum) (struct compnum) (struct ratnum))) (or float (struct compnum))) ((float) (float) (##core#inline_allocate ("C_a_i_flonum_log" 4) #(1)))) (numbers#expt (#(procedure #:clean #:enforce) numbers#expt ((or fixnum float (struct bignum) (struct compnum) (struct ratnum)) (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) (or fixnum float (struct bignum) (struct compnum) (struct ratnum))) ((float float) (float) (##core#inline_allocate ("C_a_i_flonum_expt" 4) #(1) #(2)))) (numbers#sqrt (#(procedure #:clean #:enforce) numbers#sqrt ((or fixnum float (struct bignum) (struct compnum) (struct ratnum))) (or float (struct compnum))) ((float) (float) (##core#inline_allocate ("C_a_i_flonum_sqrt" 4) #(1)))) (numbers#sin (#(procedure #:clean #:enforce) numbers#sin ((or fixnum float (struct bignum) (struct compnum) (struct ratnum))) (or float (struct compnum))) ((float) (float) (##core#inline_allocate ("C_a_i_flonum_sin" 4) #(1)))) (numbers#cos (#(procedure #:clean #:enforce) numbers#cos ((or fixnum float (struct bignum) (struct compnum) (struct ratnum))) (or float (struct compnum))) ((float) (float) (##core#inline_allocate ("C_a_i_flonum_cos" 4) #(1)))) (numbers#tan (#(procedure #:clean #:enforce) numbers#tan ((or fixnum float (struct bignum) (struct compnum) (struct ratnum))) (or float (struct compnum))) ((float) (float) (##core#inline_allocate ("C_a_i_flonum_tan" 4) #(1)))) (numbers#asin (#(procedure #:clean #:enforce) numbers#asin ((or fixnum float (struct bignum) (struct compnum) (struct ratnum))) (or float (struct compnum))) ;; Unfortunately this doesn't work when the number is > 1.0 (returns compnum) #;((float) (float) (##core#inline_allocate ("C_a_i_flonum_asin" 4) #(1)))) (numbers#acos (#(procedure #:clean #:enforce) numbers#acos ((or fixnum float (struct bignum) (struct compnum) (struct ratnum))) (or float (struct compnum))) ;; Unfortunately this doesn't work when the number is > 1.0 (returns compnum) #;((float) (float) (##core#inline_allocate ("C_a_i_flonum_acos" 4) #(1)))) (numbers#atan (#(procedure #:clean #:enforce) numbers#atan ((or fixnum float (struct bignum) (struct compnum) (struct ratnum)) #!optional number) (or float (struct compnum))) ((float) (float) (##core#inline_allocate ("C_a_i_flonum_atan" 4) #(1))) ((float float) (float) (##core#inline_allocate ("C_a_i_flonum_atan2" 4) #(1) #(2)))) (numbers#angle (#(procedure #:clean #:enforce) numbers#angle ((or float fixnum (struct compnum) (struct bignum) (struct ratnum))) float) ((float) (##core#inline_allocate ("C_a_i_flonum_atan2" 4) '0.0 #(1))) ((fixnum) (##core#inline_allocate ("C_a_i_flonum_atan2" 4) '0.0 (##core#inline_allocate ("C_a_i_fix_to_flo" 4) #(1))))) (numbers#magnitude (#(procedure #:clean #:enforce) numbers#magnitude ((or float fixnum (struct compnum) (struct bignum) (struct ratnum))) (or float fixnum (struct bignum) (struct ratnum))) (((or float fixnum (struct bignum) (struct ratnum))) (numbers#abs #(1)))) (numbers#number->string (#(procedure #:clean #:enforce) numbers#number->string ((or fixnum float (struct bignum) (struct compnum) (struct ratnum)) #!optional fixnum) string) ((fixnum) (##sys#fixnum->string #(1)))) (numbers#string->number (#(procedure #:clean #:enforce) numbers#string->number (string #!optional fixnum) (or fixnum float (struct bignum) (struct compnum) (struct ratnum) boolean)))