klisp

an open source interpreter for the Kernel Programming Language.
git clone http://git.hanabi.in/repos/klisp.git
Log | Files | Refs | README

kgnumbers.c (82635B)


      1 /*
      2 ** kgnumbers.c
      3 ** Numbers features for the ground environment
      4 ** See Copyright Notice in klisp.h
      5 */
      6 
      7 /*
      8 ** TODO: Many real operations are done by converting to bigint/bigrat
      9 ** (like numerator and gcd), these should be done in doubles directly
     10 */
     11 
     12 #include <assert.h>
     13 #include <stdio.h>
     14 #include <string.h>
     15 #include <stdlib.h>
     16 #include <stdbool.h>
     17 #include <stdint.h>
     18 #include <inttypes.h> /* for string conversion */
     19 
     20 #include "kstate.h"
     21 #include "kobject.h"
     22 #include "kapplicative.h"
     23 #include "koperative.h"
     24 #include "kcontinuation.h"
     25 #include "kerror.h"
     26 #include "ksymbol.h"
     27 #include "kinteger.h"
     28 #include "krational.h"
     29 #include "kreal.h"
     30 
     31 #include "kghelpers.h"
     32 #include "kgnumbers.h"
     33 
     34 /* 15.5.1? number?, finite?, integer? */
     35 /* use ftypep & ftypep_predp */
     36 
     37 /* 12.5.2 =? */
     38 /* uses typed_bpredp */
     39 
     40 /* 12.5.3 <?, <=?, >?, >=? */
     41 /* use typed_bpredp */
     42 
     43 /* Helpers for typed binary predicates */
     44 /* XXX: this should probably be in a file knumber.h but there is no real need for 
     45    that file yet */
     46 
     47 /* this will come handy when there are more numeric types,
     48    it is intended to be used in switch */
     49 /* MAYBE: change to return -1, 0, 1 to indicate which type is bigger, and
     50    return min & max in two extra pointers passed in. Change name to
     51    classify_types */
     52 static inline int32_t max_ttype(TValue obj1, TValue obj2)
     53 {
     54     int32_t t1 = ttype(obj1);
     55     int32_t t2 = ttype(obj2);
     56 
     57     return (t1 > t2? t1 : t2);
     58 }
     59 
     60 static inline int32_t min_ttype(TValue obj1, TValue obj2)
     61 {
     62     int32_t t1 = ttype(obj1);
     63     int32_t t2 = ttype(obj2);
     64 
     65     return (t1 < t2? t1 : t2);
     66 }
     67 
     68 /* helper to make both arguments inexact if one of them is,
     69    n1 & n2 should be variable names that may be overwritten */
     70 /* GC: There is no problem because for now all inexact are stack
     71    allocated */
     72 #define kensure_same_exactness(K, n1, n2)       \
     73     ({if (ttisinexact(n1) || ttisinexact(n2)) { \
     74             n1 = kexact_to_inexact(K, n1);      \
     75             n2 = kexact_to_inexact(K, n2);      \
     76         }})
     77 
     78 
     79 /* ASK John: this isn't quite right I think. The problem is with implicit 
     80    conversion to inexact. This can cause issues for example if two different
     81    exact numbers are compared with an inexact number that could correspong to 
     82    both (because it is too big and lacks precission for example), this would 
     83    behave differently depending on the order (=? #e1 #i #e2) would return
     84    true & (=? #e1 #e2 #i) wourld return false. Maybe all numbers should be
     85    converted to inexact. Also what happens with over & underflows? */
     86 
     87 /* ASK John: the same will probably apply to many combiners..., MAYBE shuld
     88    check scheme implementations... */
     89 
     90 /* TEMP: for now only reals, no complex numbers */
     91 bool knum_eqp(klisp_State *K, TValue n1, TValue n2) 
     92 { 
     93     /* for simplicity if one is inexact convert the other to inexact */
     94     /* ASK John what happens on under & overflow, probably an error shouldn't 
     95        be signaled but instead inexact should be converted to exact to perform
     96        the check?? */
     97     kensure_same_exactness(K, n1, n2);
     98 
     99     switch(max_ttype(n1, n2)) {
    100     case K_TFIXINT:
    101         return ivalue(n1) == ivalue(n2);
    102     case K_TBIGINT:
    103         if (min_ttype(n1, n2) != K_TBIGINT) {
    104             /* NOTE: no fixint is =? to a bigint */
    105             return false;
    106         } else {
    107             /* both are bigints */
    108             return kbigint_eqp(n1, n2);
    109         }
    110     case K_TBIGRAT:
    111         if (min_ttype(n1, n2) != K_TBIGRAT) {
    112             /* NOTE: no fixint or bigint is =? to a bigrat */
    113             return false;
    114         } else {
    115             /* both are bigints */
    116             return kbigrat_eqp(K, n1, n2);
    117         }
    118     case K_TEINF:
    119         return (tv_equal(n1, n2));
    120     case K_TDOUBLE:
    121         return (tv_equal(n1, n2));
    122     case K_TIINF: /* if the other was exact it was converted already */
    123         return (tv_equal(n1, n2));
    124     case K_TRWNPV: 
    125     case K_TUNDEFINED: /* no primary value, should throw an error */
    126         /* TEMP: this was already contemplated in type predicate */
    127     default:
    128         klispE_throw_simple(K, "unsupported type");
    129         return false;
    130     }
    131 }
    132 
    133 bool knum_ltp(klisp_State *K, TValue n1, TValue n2) 
    134 { 
    135     /* for simplicity if one is inexact convert the other to inexact */
    136     kensure_same_exactness(K, n1, n2);
    137 
    138     switch(max_ttype(n1, n2)) {
    139     case K_TFIXINT:
    140         return ivalue(n1) < ivalue(n2);
    141     case K_TBIGINT: {
    142         kensure_bigint(n1);
    143         kensure_bigint(n2);
    144         return kbigint_ltp(n1, n2);
    145     }
    146     case K_TBIGRAT: {
    147         kensure_bigrat(n1);
    148         kensure_bigrat(n2);
    149         return kbigrat_ltp(K, n1, n2);
    150     }
    151     case K_TDOUBLE: /* both must be double, all inferior types
    152                        convert to either double or inexact infinity */
    153         return (dvalue(n1) < dvalue(n2));
    154     case K_TEINF:
    155         return !tv_equal(n1, n2) && (tv_equal(n1, KEMINF) ||
    156                                      tv_equal(n2, KEPINF));
    157     case K_TIINF: /* if the other was exact it was converted already */
    158         return !tv_equal(n1, n2) && (tv_equal(n1, KIMINF) ||
    159                                      tv_equal(n2, KIPINF));
    160     case K_TRWNPV: 
    161     case K_TUNDEFINED: /* no primary value, should throw an error */
    162         /* TEMP: this was already contemplated in type predicate */
    163     default:
    164         klispE_throw_simple(K, "unsupported type");
    165         return false;
    166     }
    167 }
    168 
    169 bool knum_lep(klisp_State *K, TValue n1, TValue n2) 
    170 { 
    171     return !knum_ltp(K, n2, n1); 
    172 }
    173 bool knum_gtp(klisp_State *K, TValue n1, TValue n2) 
    174 { 
    175     return knum_ltp(K, n2, n1); 
    176 }
    177 bool knum_gep(klisp_State *K, TValue n1, TValue n2) 
    178 { 
    179     return !knum_ltp(K, n1, n2); 
    180 }
    181 
    182 /*
    183 ** Helper to check strict arithmetic flag if the result may not
    184 ** have a primary value
    185 */
    186 /* may evaluate K & n more than once */
    187 #define arith_return(K, n)                                          \
    188     ({ if (ttisnwnpv(n) && kcurr_strict_arithp(K)) {                \
    189             klispE_throw_simple_with_irritants(K, "result has no "	\
    190                                                "primary value",		\
    191                                                1, n);               \
    192             return KINERT;                                          \
    193         } else { return n;}})
    194 
    195 /* may evaluate K & n more than once */
    196 #define arith_kapply_cc(K, n)                                       \
    197     ({ if (ttisnwnpv(n) && kcurr_strict_arithp(K)) {                \
    198             klispE_throw_simple_with_irritants(K, "result has no "	\
    199                                                "primary value",		\
    200                                                1, n);               \
    201             return;                                                 \
    202         } else { kapply_cc(K, n); return;}})
    203 
    204 
    205 
    206 /* REFACTOR/MAYBE: add small inlineable plus that
    207    first tries fixint addition and if that fails calls knum_plus */
    208 
    209 /* May throw an error */
    210 /* GC: assumes n1 & n2 rooted */
    211 TValue knum_plus(klisp_State *K, TValue n1, TValue n2)
    212 {
    213     kensure_same_exactness(K, n1, n2);
    214     TValue res; /* used for results with no primary value */
    215     switch(max_ttype(n1, n2)) {
    216     case K_TFIXINT: {
    217         int64_t res = (int64_t) ivalue(n1) + (int64_t) ivalue(n2);
    218         if (res >= (int64_t) INT32_MIN &&
    219             res <= (int64_t) INT32_MAX) {
    220             return i2tv((int32_t) res);
    221         } /* else fall through */
    222     }
    223     case K_TBIGINT: {
    224         kensure_bigint(n1);
    225         kensure_bigint(n2);
    226         return kbigint_plus(K, n1, n2);
    227     }
    228     case K_TBIGRAT: {
    229         kensure_bigrat(n1);
    230         kensure_bigrat(n2);
    231         return kbigrat_plus(K, n1, n2);
    232     }
    233     case K_TDOUBLE: {
    234         double res = dvalue(n1) + dvalue(n2);
    235         /* check under & overflow */
    236         if (kcurr_strict_arithp(K)) {
    237             if (res == 0 && dvalue(n1) != -dvalue(n2)) {
    238                 klispE_throw_simple(K, "underflow");
    239                 return KINERT;
    240             } else if (isinf(res)) {
    241                 klispE_throw_simple(K, "overflow");
    242                 return KINERT;
    243             } 
    244         }
    245         /* correctly encapsulate infinities and -0.0 */
    246         return ktag_double(res);
    247     }
    248     case K_TEINF:
    249         if (!ttiseinf(n1))
    250             return n2;
    251         else if (!ttiseinf(n2))
    252             return n1;
    253         if (tv_equal(n1, n2))
    254             return n1;
    255         else { /* no primary value; handle error at the end of function */
    256             res = KRWNPV;
    257             break; 
    258         }
    259     case K_TIINF:
    260         if (!ttisiinf(n1))
    261             return n2;
    262         else if (!ttisiinf(n2))
    263             return n1;
    264         if (tv_equal(n1, n2))
    265             return n1;
    266         else { /* no primary value; handle error at the end of function */
    267             res = KRWNPV;
    268             break;
    269         }
    270     case K_TRWNPV: /* no primary value */
    271         res = KRWNPV;
    272         break;
    273     case K_TUNDEFINED: /* undefined */
    274         res = KUNDEF;
    275         break;
    276     default:
    277         klispE_throw_simple(K, "unsupported type");
    278         return KINERT;
    279     }
    280 
    281     /* check for no primary value and value of strict arith */
    282     arith_return(K, res);
    283 }
    284 
    285 /* May throw an error */
    286 /* GC: assumes n1 & n2 rooted */
    287 TValue knum_times(klisp_State *K, TValue n1, TValue n2)
    288 {
    289     kensure_same_exactness(K, n1, n2);
    290     TValue res; /* used for results with no primary value */
    291     switch(max_ttype(n1, n2)) {
    292     case K_TFIXINT: {
    293         int64_t res = (int64_t) ivalue(n1) * (int64_t) ivalue(n2);
    294         if (res >= (int64_t) INT32_MIN &&
    295             res <= (int64_t) INT32_MAX) {
    296             return i2tv((int32_t) res);
    297         } /* else fall through */
    298     }
    299     case K_TBIGINT: {
    300         kensure_bigint(n1);
    301         kensure_bigint(n2);
    302         return kbigint_times(K, n1, n2);
    303     }
    304     case K_TBIGRAT: {
    305         kensure_bigrat(n1);
    306         kensure_bigrat(n2);
    307         return kbigrat_times(K, n1, n2);
    308     }
    309     case K_TDOUBLE: {
    310         double res = dvalue(n1) * dvalue(n2);
    311         /* check under & overflow */
    312         if (kcurr_strict_arithp(K)) {
    313             if (res == 0 && dvalue(n1) != 0.0 && dvalue(n2) != 0.00) {
    314                 klispE_throw_simple(K, "underflow");
    315                 return KINERT;
    316             } else if (isinf(res)) {
    317                 klispE_throw_simple(K, "overflow");
    318                 return KINERT;
    319             }
    320         }
    321         /* correctly encapsulate infinities and -0.0 */
    322         return ktag_double(res);
    323     }
    324     case K_TEINF:
    325         if (!ttiseinf(n1) || !ttiseinf(n2)) {
    326             if (kfast_zerop(n1) || kfast_zerop(n2)) {
    327                 /* report: #e+infinity * 0 has no primary value */
    328                 res = KRWNPV;
    329                 break;
    330             } else if (ttisexact(n1) && ttisexact(n2))
    331                 return knum_same_signp(K, n1, n2)? KEPINF : KEMINF;
    332             else 
    333                 return knum_same_signp(K, n1, n2)? KIPINF : KIMINF;
    334         } else
    335             return (tv_equal(n1, n2))? KEPINF : KEMINF;
    336     case K_TIINF:
    337         if (!ttisiinf(n1) || !ttisiinf(n2)) {
    338             if (kfast_zerop(n1) || kfast_zerop(n2)) {
    339                 /* report: #i[+-]infinity * 0 has no primary value */
    340                 res = KRWNPV;
    341                 break;
    342             } else
    343                 return knum_same_signp(K, n1, n2)? KIPINF : KIMINF;
    344         } else
    345             return (tv_equal(n1, n2))? KIPINF : KIMINF;
    346     case K_TRWNPV:
    347         res = KRWNPV;
    348         break;
    349     case K_TUNDEFINED:
    350         res = KUNDEF;
    351         break;
    352     default:
    353         klispE_throw_simple(K, "unsupported type");
    354         return KINERT;
    355     }
    356 
    357     /* check for no primary value and value of strict arith */
    358     arith_return(K, res);
    359 }
    360 
    361 /* May throw an error */
    362 /* GC: assumes n1 & n2 rooted */
    363 TValue knum_minus(klisp_State *K, TValue n1, TValue n2)
    364 {
    365     kensure_same_exactness(K, n1, n2);
    366     TValue res; /* used for results with no primary value */
    367 
    368     switch(max_ttype(n1, n2)) {
    369     case K_TFIXINT: {
    370         int64_t res = (int64_t) ivalue(n1) - (int64_t) ivalue(n2);
    371         if (res >= (int64_t) INT32_MIN &&
    372             res <= (int64_t) INT32_MAX) {
    373             return i2tv((int32_t) res);
    374         } /* else fall through */
    375     }
    376     case K_TBIGINT: {
    377         kensure_bigint(n1);
    378         kensure_bigint(n2);
    379         return kbigint_minus(K, n1, n2);
    380     }
    381     case K_TBIGRAT: {
    382         kensure_bigrat(n1);
    383         kensure_bigrat(n2);
    384         return kbigrat_minus(K, n1, n2);
    385     }
    386     case K_TDOUBLE: {
    387         /* both are double */
    388         double res = dvalue(n1) - dvalue(n2);
    389         /* check under & overflow */
    390         if (kcurr_strict_arithp(K)) {
    391             if (res == 0 && dvalue(n1) != dvalue(n2)) {
    392                 klispE_throw_simple(K, "underflow");
    393                 return KINERT;
    394             } else if (isinf(res)) {
    395                 klispE_throw_simple(K, "overflow");
    396                 return KINERT;
    397             } 
    398         }
    399         /* correctly encapsulate infinities and -0.0 */
    400         return ktag_double(res);
    401     }
    402     case K_TEINF:
    403         if (!ttiseinf(n1))
    404             return kneg_inf(n2);
    405         else if (!ttiseinf(n2))
    406             return n1;
    407         if (tv_equal(n1, n2)) {
    408             /* no primary value; handle error at the end of function */
    409             res = KRWNPV;
    410             break;
    411         } else
    412             return n1;
    413     case K_TIINF:
    414         if (!ttisiinf(n1))
    415             return kneg_inf(n2);
    416         else if (!ttisiinf(n2))
    417             return n1;
    418         if (tv_equal(n1, n2)) {
    419             /* no primary value; handle error at the end of function */
    420             res = KRWNPV;
    421             break;
    422         } else 
    423             return n1;
    424     case K_TRWNPV: /* no primary value */
    425         res = KRWNPV;
    426         break;
    427     case K_TUNDEFINED: /* undefined */
    428         res = KUNDEF;
    429         break;
    430     default:
    431         klispE_throw_simple(K, "unsupported type");
    432         return KINERT;
    433     }
    434 
    435     /* check for no primary value and value of strict arith */
    436     arith_return(K, res);
    437 }
    438 
    439 /* May throw an error */
    440 /* GC: assumes n1 & n2 rooted */
    441 TValue knum_divided(klisp_State *K, TValue n1, TValue n2)
    442 {
    443     kensure_same_exactness(K, n1, n2);
    444     TValue res; /* used for results with no primary value */
    445 
    446     /* first check the most common error, division by zero */
    447     if (kfast_zerop(n2)) {
    448         klispE_throw_simple(K, "division by zero");
    449         return KINERT;
    450     }
    451 
    452     switch(max_ttype(n1, n2)) {
    453     case K_TFIXINT: {
    454         int64_t res = (int64_t) ivalue(n1) / (int64_t) ivalue(n2);
    455         int64_t rem = (int64_t) ivalue(n1) % (int64_t) ivalue(n2);
    456         if (rem == 0 && res >= (int64_t) INT32_MIN &&
    457             res <= (int64_t) INT32_MAX) {
    458             return i2tv((int32_t) res);
    459         } /* else fall through */
    460     }
    461     case K_TBIGINT: /* just handle it as a rational */
    462     case K_TBIGRAT: {
    463         kensure_bigrat(n1);
    464         kensure_bigrat(n2);
    465         return kbigrat_divided(K, n1, n2);
    466     }
    467     case K_TDOUBLE: {
    468         double res = dvalue(n1) / dvalue(n2);
    469         /* check under & overflow */
    470         if (kcurr_strict_arithp(K)) {
    471             if (res == 0 && dvalue(n1) != 0.0) {
    472                 klispE_throw_simple(K, "underflow");
    473                 return KINERT;
    474             } else if (isinf(res)) {
    475                 klispE_throw_simple(K, "overflow");
    476                 return KINERT;
    477             }
    478         }
    479         /* correctly encapsulate infinities and -0.0 */
    480         return ktag_double(res);
    481     }
    482     case K_TEINF: {
    483         if (ttiseinf(n1) && ttiseinf(n2)) {
    484             klispE_throw_simple(K, "infinity divided by infinity");
    485             return KINERT;
    486         } else if (ttiseinf(n1)) {
    487             return knum_same_signp(K, n1, n2)? KEPINF : KEMINF;
    488         } else { /* ttiseinf(n2) */
    489             return i2tv(0);
    490         }
    491     }
    492     case K_TIINF:
    493         if (ttisiinf(n1) && ttisiinf(n2)) {
    494             klispE_throw_simple(K, "infinity divided by infinity");
    495             return KINERT;
    496         } else if (ttisiinf(n1)) {
    497             return knum_same_signp(K, n1, n2)? KIPINF : KIMINF;
    498         } else { /* ttiseinf(n2) */
    499             /* NOTE: I guess this doens't count as underflow */
    500             return d2tv(0.0);
    501         }
    502     case K_TRWNPV:
    503         res = KRWNPV;
    504         break;
    505     case K_TUNDEFINED:
    506         res = KUNDEF;
    507         break;
    508     default:
    509         klispE_throw_simple(K, "unsupported type");
    510         return KINERT;
    511     }
    512 
    513     /* check for no primary value and value of strict arith */
    514     arith_return(K, res);
    515 }
    516 
    517 /* GC: assumes n rooted */
    518 TValue knum_abs(klisp_State *K, TValue n)
    519 {
    520     switch(ttype(n)) {
    521     case K_TFIXINT: {
    522         int32_t i = ivalue(n);
    523         if (i != INT32_MIN)
    524             return (i < 0? i2tv(-i) : n);
    525         /* if i == INT32_MIN, fall through */
    526         /* MAYBE: we could cache the bigint INT32_MAX+1 */
    527         /* else fall through */
    528     }
    529     case K_TBIGINT: {
    530         /* this is needed for INT32_MIN, can't be in previous
    531            case because it should be in the same block, remember
    532            the bigint is allocated on the stack. */
    533         kensure_bigint(n); 
    534         return kbigint_abs(K, n);
    535     }
    536     case K_TBIGRAT: {
    537         return kbigrat_abs(K, n);
    538     }
    539     case K_TDOUBLE: {
    540         return ktag_double(fabs(dvalue(n)));
    541     }
    542     case K_TEINF:
    543         return KEPINF;
    544     case K_TIINF:
    545         return KIPINF;
    546     case K_TRWNPV: 
    547         /* ASK John: is the error here okay */
    548         arith_return(K, KRWNPV);
    549     default:
    550         /* shouldn't happen */
    551         klispE_throw_simple(K, "unsupported type");
    552         return KINERT;
    553     }
    554 }
    555 
    556 /* unlike the kernel gcd this returns |n| for gcd(n, 0) and gcd(0, n) and
    557    0 for gcd(0, 0) */
    558 /* GC: assumes n1 & n2 rooted */
    559 TValue knum_gcd(klisp_State *K, TValue n1, TValue n2)
    560 {
    561     /* this is not so nice but simplifies some cases */
    562     /* XXX: this may cause overflows! */
    563     kensure_same_exactness(K, n1, n2);
    564 
    565     switch(max_ttype(n1, n2)) {
    566     case K_TFIXINT: {
    567         int64_t gcd = kgcd32_64(ivalue(n1), ivalue(n2));
    568         /* May fail for gcd(INT32_MIN, INT32_MIN) because
    569            it would return INT32_MAX+1 */
    570         if (kfit_int32_t(gcd)) 
    571             return i2tv((int32_t) gcd);
    572         /* else fall through */
    573     }
    574     case K_TBIGINT: {
    575         kensure_bigint(n1);
    576         kensure_bigint(n2);
    577         return kbigint_gcd(K, n1, n2);
    578     }
    579     case K_TDOUBLE: {
    580         krooted_vars_push(K, &n1);
    581         krooted_vars_push(K, &n2);
    582         n1 = kinexact_to_exact(K, n1);
    583         n2 = kinexact_to_exact(K, n2);
    584         TValue res = knum_gcd(K, n1, n2);
    585         krooted_tvs_push(K, res);
    586         res = kexact_to_inexact(K, res);
    587         krooted_tvs_pop(K);
    588         krooted_vars_pop(K);
    589         krooted_vars_pop(K);
    590         return res;
    591     }
    592     case K_TEINF:
    593         if (kfast_zerop(n2) || !ttiseinf(n1))
    594             return knum_abs(K, n1);
    595         else if (kfast_zerop(n1) || !ttiseinf(n2))
    596             return knum_abs(K, n2);
    597         else
    598             return KEPINF;
    599     case K_TIINF:
    600         if (kfast_zerop(n2) || !ttisiinf(n1))
    601             return knum_abs(K, n1);
    602         else if (kfast_zerop(n1) || !ttisiinf(n2))
    603             return knum_abs(K, n2);
    604         else
    605             return KIPINF;
    606     default:
    607         klispE_throw_simple(K, "unsupported type");
    608         return KINERT;
    609     }
    610 }
    611 
    612 /* may throw an error if one of the arguments if zero */
    613 /* GC: assumes n1 & n2 rooted */
    614 TValue knum_lcm(klisp_State *K, TValue n1, TValue n2)
    615 {
    616     /* this is not so nice but simplifies some cases */
    617     /* XXX: this may cause overflows! */
    618     kensure_same_exactness(K, n1, n2);
    619     
    620     /* get this out of the way first */
    621     if (kfast_zerop(n1) || kfast_zerop(n2)) {
    622         arith_return(K, KRWNPV);
    623     }
    624 
    625     switch(max_ttype(n1, n2)) {
    626     case K_TFIXINT: {
    627         int64_t lcm = klcm32_64(ivalue(n1), ivalue(n2));
    628         /* May fail for lcm(INT32_MIN, 1) because
    629            it would return INT32_MAX+1 */
    630         if (kfit_int32_t(lcm)) 
    631             return i2tv((int32_t) lcm);
    632         /* else fall through */
    633     }
    634     case K_TBIGINT: {
    635         kensure_bigint(n1);
    636         kensure_bigint(n2);
    637         return kbigint_lcm(K, n1, n2);
    638     }
    639     case K_TDOUBLE: {
    640         krooted_vars_push(K, &n1);
    641         krooted_vars_push(K, &n2);
    642         n1 = kinexact_to_exact(K, n1);
    643         n2 = kinexact_to_exact(K, n2);
    644         TValue res = knum_lcm(K, n1, n2);
    645         krooted_tvs_push(K, res);
    646         res = kexact_to_inexact(K, res);
    647         krooted_tvs_pop(K);
    648         krooted_vars_pop(K);
    649         krooted_vars_pop(K);
    650         return res;
    651     }
    652     case K_TEINF:
    653         return KEPINF;
    654     case K_TIINF:
    655         return KIPINF;
    656     default:
    657         klispE_throw_simple(K, "unsupported type");
    658         return KINERT;
    659     }
    660 }
    661 
    662 /* GC: assumes n is rooted */
    663 TValue knum_numerator(klisp_State *K, TValue n)
    664 {
    665     switch(ttype(n)) {
    666     case K_TFIXINT:
    667     case K_TBIGINT:
    668         return n;
    669     case K_TBIGRAT:
    670         return kbigrat_numerator(K, n);
    671     case K_TDOUBLE: {
    672         TValue res = kinexact_to_exact(K, n);
    673         krooted_vars_push(K, &res);
    674         res = knum_numerator(K, res);
    675         res = kexact_to_inexact(K, res);
    676         krooted_vars_pop(K);
    677         return res;
    678     }
    679 /*    case K_TEINF: infinities are not rational! */
    680     default:
    681         klispE_throw_simple(K, "unsupported type");
    682         return KINERT;
    683     }
    684 }
    685 
    686 /* GC: assumes n is rooted */
    687 TValue knum_denominator(klisp_State *K, TValue n)
    688 {
    689     switch(ttype(n)) {
    690     case K_TFIXINT:
    691     case K_TBIGINT:
    692         return i2tv(1); /* denominator of integer is always (+)1 */
    693     case K_TBIGRAT:
    694         return kbigrat_denominator(K, n);
    695     case K_TDOUBLE: {
    696         TValue res = kinexact_to_exact(K, n);
    697         krooted_vars_push(K, &res);
    698         res = knum_denominator(K, res);
    699         res = kexact_to_inexact(K, res);
    700         krooted_vars_pop(K);
    701         return res;
    702     }
    703 /*    case K_TEINF: infinities are not rational! */
    704     default:
    705         klispE_throw_simple(K, "unsupported type");
    706         return KINERT;
    707     }
    708 }
    709 
    710 /* GC: assumes n is rooted */
    711 TValue knum_real_to_integer(klisp_State *K, TValue n, kround_mode mode)
    712 {
    713     switch(ttype(n)) {
    714     case K_TFIXINT:
    715     case K_TBIGINT:
    716         return n; /* integers are easy */
    717     case K_TBIGRAT:
    718         return kbigrat_to_integer(K, n, mode);
    719     case K_TDOUBLE:
    720         return kdouble_to_integer(K, n, mode);
    721     case K_TEINF: 
    722         klispE_throw_simple(K, "infinite value");
    723         return KINERT;
    724     case K_TIINF: 
    725         klispE_throw_simple(K, "infinite value");
    726         return KINERT;
    727     case K_TRWNPV:
    728         arith_return(K, KRWNPV);
    729     case K_TUNDEFINED:
    730         /* undefined in not a real, shouldn't get here, fall through */
    731     default:
    732         klispE_throw_simple(K, "unsupported type");
    733         return KINERT;
    734     }
    735 }
    736 
    737 TValue knum_simplest_rational(klisp_State *K, TValue n1, TValue n2)
    738 {
    739     /* this is not so nice but simplifies some cases */
    740     /* XXX: this may cause overflows! */
    741     kensure_same_exactness(K, n1, n2);
    742 
    743     /* first check that case that n1 > n2 */
    744     if (knum_gtp(K, n1, n2)) {
    745         klispE_throw_simple(K, "x0 doesn't exists (n1 > n2)");
    746         return KINERT;
    747     }
    748 
    749     /* we know that n1 <= n2 */
    750     switch(max_ttype(n1, n2)) {
    751     case K_TFIXINT:
    752     case K_TBIGINT: /* for now do all with bigrat */
    753     case K_TBIGRAT: {
    754         /* we know that n1 <= n2 */
    755         kensure_bigrat(n1);
    756         kensure_bigrat(n2);
    757         return kbigrat_simplest_rational(K, n1, n2);
    758     }
    759     case K_TDOUBLE: {
    760         /* both are double, for now just convert to rational */
    761         krooted_vars_push(K, &n1);
    762         krooted_vars_push(K, &n2);
    763         n1 = kinexact_to_exact(K, n1);
    764         n2 = kinexact_to_exact(K, n2);
    765         TValue res = knum_simplest_rational(K, n1, n2);
    766         krooted_tvs_push(K, res);
    767         res = kexact_to_inexact(K, res);
    768         krooted_tvs_pop(K);
    769         krooted_vars_pop(K);
    770         krooted_vars_pop(K);
    771         return res;
    772     }
    773     case K_TEINF:
    774         /* we know that n1 <= n2 */
    775         if (tv_equal(n1, n2)) {
    776             klispE_throw_simple(K, "x0 doesn't exists (n1 == n2 & "
    777                                 "irrational)");
    778             return KINERT;
    779         } else if (knegativep(n1) && kpositivep(n2)) {
    780             return i2tv(0);
    781         } else if (knegativep(n1)) {
    782             /* n1 -inf, n2 finite negative */
    783             /* ASK John: is this behaviour for infinities ok? */
    784             /* Also in the report example both 1/3 & 1/2 are simpler than 
    785                2/5... */
    786             return knum_real_to_integer(K, n2, K_FLOOR);
    787         } else {
    788             /* n1 finite positive, n2 +inf */
    789             /* ASK John: is this behaviour for infinities ok? */
    790             return knum_real_to_integer(K, n1, K_CEILING);
    791         }
    792     case K_TIINF:
    793         /* we know that n1 <= n2 */
    794         if (tv_equal(n1, n2)) {
    795             klispE_throw_simple(K, "result with no primary value");
    796             return KINERT;
    797         } else if (knegativep(n1) && kpositivep(n2)) {
    798             return d2tv(0.0);
    799         } else if (knegativep(n1)) {
    800             /* n1 -inf, n2 finite negative */
    801             /* ASK John: is this behaviour for infinities ok? */
    802             /* Also in the report example both 1/3 & 1/2 are simpler than 
    803                2/5... */
    804             return knum_real_to_integer(K, n2, K_FLOOR);
    805         } else {
    806             /* n1 finite positive, n2 +inf */
    807             /* ASK John: is this behaviour for infinities ok? */
    808             return knum_real_to_integer(K, n1, K_CEILING);
    809         }
    810     case K_TRWNPV:
    811         arith_return(K, KRWNPV);
    812         /* complex and undefined should be captured by type predicate */
    813     default:
    814         klispE_throw_simple(K, "unsupported type");
    815         return KINERT;
    816     }
    817 }
    818 
    819 TValue knum_rationalize(klisp_State *K, TValue n1, TValue n2)
    820 {
    821     /* this is not so nice but simplifies some cases */
    822     /* XXX: this may cause overflows! */
    823     kensure_same_exactness(K, n1, n2);
    824 
    825     switch(max_ttype(n1, n2)) {
    826     case K_TFIXINT:
    827     case K_TBIGINT: /* for now do all with bigrat */
    828     case K_TBIGRAT: {
    829         /* we know that n1 <= n2 */
    830         kensure_bigrat(n1);
    831         kensure_bigrat(n2);
    832         return kbigrat_rationalize(K, n1, n2);
    833     }
    834     case K_TDOUBLE: {
    835         /* both are double, for now just convert to rational */
    836         krooted_vars_push(K, &n1);
    837         krooted_vars_push(K, &n2);
    838         n1 = kinexact_to_exact(K, n1);
    839         n2 = kinexact_to_exact(K, n2);
    840         TValue res = knum_rationalize(K, n1, n2);
    841         krooted_tvs_push(K, res);
    842         res = kexact_to_inexact(K, res);
    843         krooted_tvs_pop(K);
    844         krooted_vars_pop(K);
    845         krooted_vars_pop(K);
    846         return res;
    847     }
    848     case K_TEINF:
    849         if (kfinitep(n1) || !kfinitep(n2)) {
    850             return i2tv(0);
    851         } else { /* infinite n1, finite n2 */
    852             /* ASK John: is this behaviour for infinities ok? */
    853             klispE_throw_simple(K, "x0 doesn't exists");
    854             return KINERT;
    855         }
    856     case K_TIINF:
    857         if (kfinitep(n1) || !kfinitep(n2)) {
    858             return d2tv(0.0);
    859         } else { /* infinite n1, finite n2 */
    860             /* ASK John: is this behaviour for infinities ok? */
    861             klispE_throw_simple(K, "x0 doesn't exists");
    862             return KINERT;
    863         }
    864     default:
    865         klispE_throw_simple(K, "unsupported type");
    866         return KINERT;
    867     }
    868 }
    869 
    870 /* 12.5.4 + */
    871 void kplus(klisp_State *K)
    872 {
    873     TValue *xparams = K->next_xparams;
    874     TValue ptree = K->next_value;
    875     TValue denv = K->next_env;
    876     klisp_assert(ttisenvironment(K->next_env));
    877     UNUSED(denv);
    878     UNUSED(xparams);
    879     /* cycles are allowed, loop counting pairs */
    880     int32_t pairs, cpairs; 
    881     check_typed_list(K, knumberp, true, ptree, &pairs, &cpairs);
    882     int32_t apairs = pairs - cpairs;
    883 
    884     TValue res;
    885 
    886     /* first the acyclic part */
    887     TValue ares = i2tv(0);
    888     krooted_vars_push(K, &ares);
    889     TValue tail = ptree;
    890 
    891     while(apairs--) {
    892         TValue first = kcar(tail);
    893         tail = kcdr(tail);
    894 
    895         /* may throw an exception */
    896         ares = knum_plus(K, ares, first);
    897     }
    898 
    899     /* next the cyclic part */
    900     TValue cres = i2tv(0); /* push it only if needed */
    901 
    902     if (cpairs == 0 && !ttisnwnpv(ares)) { /* #undefined or #real */
    903         /* speed things up if there is no cycle and 
    904            no possible error (on no primary value) */
    905         res = ares;
    906         krooted_vars_pop(K);
    907     } else {
    908         bool all_zero = true;
    909         bool all_exact = true;
    910 
    911         krooted_vars_push(K, &cres);
    912         while(cpairs--) {
    913             TValue first = kcar(tail);
    914             tail = kcdr(tail);
    915 
    916             all_zero = all_zero && kfast_zerop(first);
    917             all_exact = all_exact && ttisexact(first);
    918 
    919             cres = knum_plus(K, cres, first);
    920         }
    921 
    922         if (ttisnwnpv(cres)) /* #undefined or #real */
    923             ; /* do nothing, check is made later */
    924         else if (kfast_zerop(cres)) {
    925             if (!all_zero)
    926                 cres = KRWNPV; /* check is made later */
    927         } else if (all_exact)
    928             cres = knegativep(cres)? KEMINF : KEPINF;
    929         else
    930             cres = knegativep(cres)? KIMINF : KIPINF;
    931 
    932         /* here if any of the two has no primary an error is signaled */
    933         res = knum_plus(K, ares, cres);
    934         krooted_vars_pop(K);
    935         krooted_vars_pop(K);
    936     }
    937     kapply_cc(K, res);
    938 }
    939 
    940 /* 12.5.5 * */
    941 void ktimes(klisp_State *K)
    942 {
    943     TValue *xparams = K->next_xparams;
    944     TValue ptree = K->next_value;
    945     TValue denv = K->next_env;
    946     klisp_assert(ttisenvironment(K->next_env));
    947     UNUSED(denv);
    948     UNUSED(xparams);
    949     /* cycles are allowed, loop counting pairs */
    950     int32_t pairs, cpairs; 
    951     check_typed_list(K, knumberp, true, ptree, &pairs, &cpairs);
    952     int32_t apairs = pairs - cpairs;
    953 
    954     TValue res;
    955 
    956     /* first the acyclic part */
    957     TValue ares = i2tv(1);
    958     TValue tail = ptree;
    959 
    960     krooted_vars_push(K, &ares);
    961     while(apairs--) {
    962         TValue first = kcar(tail);
    963         tail = kcdr(tail);
    964         ares = knum_times(K, ares, first);
    965     }
    966 
    967     /* next the cyclic part */
    968     TValue cres = i2tv(1);
    969 
    970     if (cpairs == 0 && !ttisnwnpv(ares)) { /* #undefined or #real */
    971         /* speed things up if there is no cycle */
    972         res = ares;
    973         krooted_vars_pop(K);
    974     } else {
    975         bool all_one = true;
    976         bool all_exact = true;
    977 
    978         krooted_vars_push(K, &cres);
    979         while(cpairs--) {
    980             TValue first = kcar(tail);
    981             tail = kcdr(tail);
    982             all_one = all_one && kfast_onep(first);
    983             all_exact = all_exact && ttisexact(first);
    984             cres = knum_times(K, cres, first);
    985         }
    986 
    987         /* think of cres as the product of an infinite series */
    988         if (ttisnwnpv(ares))
    989             ; /* do nothing */
    990         if (kfast_zerop(cres)) 
    991             ; /* do nothing */
    992         else if (kpositivep(cres) && knum_ltp(K, cres, i2tv(1))) {
    993             if (all_exact)
    994                 cres = i2tv(0);
    995             else 
    996                 cres = d2tv(0.0);
    997         }
    998         else if (kfast_onep(cres)) {
    999             if (all_one) {
   1000                 if (all_exact)
   1001                     cres = i2tv(1);
   1002                 else
   1003                     cres = d2tv(1.0);
   1004             } else 
   1005                 cres = KRWNPV;
   1006         } else if (knum_gtp(K, cres, i2tv(1))) {
   1007             /* ASK JOHN: this is as per the report, but maybe we should check
   1008                that all elements are positive... */
   1009             cres = all_exact? KEPINF : KIPINF;
   1010         } else
   1011             cres = KRWNPV;
   1012 
   1013         /* this will throw error if necessary on no primary value */
   1014         res = knum_times(K, ares, cres);
   1015         krooted_vars_pop(K);
   1016         krooted_vars_pop(K);
   1017     } 
   1018     kapply_cc(K, res);
   1019 }
   1020 
   1021 /* 12.5.6 - */
   1022 void kminus(klisp_State *K)
   1023 {
   1024     TValue *xparams = K->next_xparams;
   1025     TValue ptree = K->next_value;
   1026     TValue denv = K->next_env;
   1027     klisp_assert(ttisenvironment(K->next_env));
   1028     UNUSED(denv);
   1029     UNUSED(xparams);
   1030     /* cycles are allowed, loop counting pairs */
   1031     int32_t pairs, cpairs;
   1032     
   1033     /* - in kernel (and unlike in scheme) requires at least 2 arguments */
   1034     if (!ttispair(ptree) || !ttispair(kcdr(ptree))) {
   1035         klispE_throw_simple(K, "at least two values are required");
   1036         return;
   1037     } else if (!knumberp(kcar(ptree))) {
   1038         klispE_throw_simple(K, "bad type on first argument (expected number)");
   1039         return;
   1040     }
   1041     TValue first_val = kcar(ptree);
   1042     check_typed_list(K, knumberp, true, kcdr(ptree), &pairs, &cpairs);
   1043     int32_t apairs = pairs - cpairs;
   1044 
   1045     TValue res;
   1046 
   1047     /* first the acyclic part */
   1048     TValue ares = i2tv(0);
   1049     TValue tail = kcdr(ptree);
   1050 
   1051     krooted_vars_push(K, &ares);
   1052 
   1053     while(apairs--) {
   1054         TValue first = kcar(tail);
   1055         tail = kcdr(tail);
   1056         ares = knum_plus(K, ares, first);
   1057     }
   1058 
   1059     /* next the cyclic part */
   1060     TValue cres = i2tv(0); /* push it only if needed */
   1061 
   1062     if (cpairs == 0 && !ttisnwnpv(ares)) { /* #undefined or #real */
   1063         /* speed things up if there is no cycle and 
   1064            no possible error (on no primary value) */
   1065         res = ares;
   1066         krooted_vars_pop(K);
   1067     } else {
   1068         bool all_zero = true;
   1069         bool all_exact = true;
   1070 
   1071         krooted_vars_push(K, &cres);
   1072         while(cpairs--) {
   1073             TValue first = kcar(tail);
   1074             tail = kcdr(tail);
   1075 
   1076             all_zero = all_zero && kfast_zerop(first);
   1077             all_exact = all_exact && ttisexact(first);
   1078 
   1079             cres = knum_plus(K, cres, first);
   1080         }
   1081 
   1082         if (ttisnwnpv(cres)) /* #undefined or #real */
   1083             ; /* do nothing, check is made later */
   1084         else if (kfast_zerop(cres)) {
   1085             if (!all_zero)
   1086                 cres = KRWNPV; /* check is made later */
   1087         } else if (all_exact)
   1088             cres = knegativep(cres)? KEMINF : KEPINF;
   1089         else
   1090             cres = knegativep(cres)? KIMINF : KIPINF;
   1091 
   1092         /* here if any of the two has no primary an error is signaled */
   1093         res = knum_plus(K, ares, cres);
   1094         krooted_vars_pop(K);
   1095         krooted_vars_pop(K);
   1096     }
   1097     /* now substract the sum of all the elements in the list to the first 
   1098        value */
   1099     krooted_tvs_push(K, res);
   1100     res = knum_minus(K, first_val, res);
   1101     krooted_tvs_pop(K);
   1102 
   1103     kapply_cc(K, res);
   1104 }
   1105 
   1106 /* 12.5.7 zero? */
   1107 /* uses ftyped_predp */
   1108 
   1109 /* Helper for zero? */
   1110 bool kzerop(TValue n) { return kfast_zerop(n); }
   1111 
   1112 /* 12.5.8 div, mod, div-and-mod */
   1113 /* use div_mod */
   1114 
   1115 /* 12.5.9 div0, mod0, div0-and-mod0 */
   1116 /* use div_mod */
   1117 
   1118 /* Helpers for div, mod, div0 and mod0 */
   1119 
   1120 int32_t kfixint_div_mod(int32_t n, int32_t d, int32_t *res_mod) 
   1121 {
   1122     int32_t div = n / d;
   1123     int32_t mod = n % d;
   1124 
   1125     /* div, mod or div-and-mod */
   1126     /* 0 <= mod0 < |d| */
   1127     if (mod < 0) {
   1128         if (d < 0) {
   1129             mod -= d;
   1130             ++div;
   1131         } else {
   1132             mod += d;
   1133             --div;
   1134         }
   1135     }
   1136     *res_mod = mod;
   1137     return div;
   1138 }
   1139 
   1140 int32_t kfixint_div0_mod0(int32_t n, int32_t d, int32_t *res_mod) 
   1141 {
   1142     int32_t div = n / d;
   1143     int32_t mod = n % d;
   1144 
   1145     /* div0, mod0 or div-and-mod0 */
   1146     /*
   1147     ** Adjust q and r so that:
   1148     ** -|d/2| <= mod0 < |d/2| which is the same as
   1149     ** dmin <= mod0 < dmax, where 
   1150     ** dmin = -floor(|d/2|) and dmax = ceil(|d/2|) 
   1151     */
   1152     int32_t dmin = -((d<0? -d : d) / 2);
   1153     int32_t dmax = ((d<0? -d : d) + 1) / 2;
   1154 	
   1155     if (mod < dmin) {
   1156         if (d < 0) {
   1157             mod -= d;
   1158             ++div;
   1159         } else {
   1160             mod += d;
   1161             --div;
   1162         }
   1163     } else if (mod >= dmax) {
   1164         if (d < 0) {
   1165             mod += d;
   1166             --div;
   1167         } else {
   1168             mod -= d;
   1169             ++div;
   1170         }
   1171     }
   1172     *res_mod = mod;
   1173     return div;
   1174 }
   1175 
   1176 /* Helper for div and mod */
   1177 #define FDIV_DIV 1
   1178 #define FDIV_MOD 2
   1179 #define FDIV_ZERO 4
   1180 
   1181 /* flags are FDIV_DIV, FDIV_MOD, FDIV_ZERO */
   1182 void kdiv_mod(klisp_State *K)
   1183 {
   1184     TValue *xparams = K->next_xparams;
   1185     TValue ptree = K->next_value;
   1186     TValue denv = K->next_env;
   1187     klisp_assert(ttisenvironment(K->next_env));
   1188     /*
   1189     ** xparams[0]: name symbol
   1190     ** xparams[1]: div_mod_flags
   1191     */
   1192     int32_t flags = ivalue(xparams[1]);
   1193 
   1194     UNUSED(denv);
   1195 
   1196     bind_2tp(K, ptree, "real", krealp, tv_n,
   1197              "real", krealp, tv_d);
   1198 
   1199     TValue tv_div, tv_mod;
   1200 
   1201     kensure_same_exactness(K, tv_n, tv_d);
   1202 
   1203     if (kfast_zerop(tv_d)) {
   1204         klispE_throw_simple(K, "division by zero");
   1205         return;
   1206     } 
   1207 
   1208     switch(max_ttype(tv_n, tv_d)) {
   1209     case K_TFIXINT:
   1210         /* NOTE: the only case were the result wouldn't fit in a fixint
   1211            is INT32_MIN divided by -1, resulting in INT32_MAX + 1.
   1212            The remainder is always < |tv_d| so no problem there, and
   1213            the quotient is always <= |tv_n|. All that said, the code to
   1214            correct the result returned by c operators / and % could cause
   1215            problems if d = INT32_MIN or d = INT32_MAX so just to be safe
   1216            we restrict d to be |d| < INT32_MAX and n to be 
   1217            |n| < INT32_MAX */
   1218         if (!(ivalue(tv_n) <= INT32_MIN+2 || ivalue(tv_n) >= INT32_MAX-1 ||
   1219               ivalue(tv_d) <= INT32_MIN+2 || ivalue(tv_d) >= INT32_MAX-1)) {
   1220             int32_t div, mod;
   1221             if ((flags & FDIV_ZERO) == 0)
   1222                 div = kfixint_div_mod(ivalue(tv_n), ivalue(tv_d), &mod);
   1223             else
   1224                 div = kfixint_div0_mod0(ivalue(tv_n), ivalue(tv_d), &mod);
   1225             tv_div = i2tv(div);
   1226             tv_mod = i2tv(mod);
   1227             break;
   1228         } /* else fall through */
   1229     case K_TBIGINT:
   1230         kensure_bigint(tv_n);
   1231         kensure_bigint(tv_d);
   1232         if ((flags & FDIV_ZERO) == 0)
   1233             tv_div = kbigint_div_mod(K, tv_n, tv_d, &tv_mod);
   1234         else
   1235             tv_div = kbigint_div0_mod0(K, tv_n, tv_d, &tv_mod);
   1236         break;
   1237     case K_TBIGRAT:
   1238         kensure_bigrat(tv_n);
   1239         kensure_bigrat(tv_d);
   1240         if ((flags & FDIV_ZERO) == 0)
   1241             tv_div = kbigrat_div_mod(K, tv_n, tv_d, &tv_mod);
   1242         else 
   1243             tv_div = kbigrat_div0_mod0(K, tv_n, tv_d, &tv_mod);
   1244         break;
   1245     case K_TDOUBLE: {
   1246         /* both are double */
   1247         double div, mod;
   1248         if ((flags & FDIV_ZERO) == 0)
   1249             div = kdouble_div_mod(dvalue(tv_n), dvalue(tv_d), &mod);
   1250         else 
   1251             div = kdouble_div0_mod0(dvalue(tv_n), dvalue(tv_d), &mod);
   1252         tv_div = ktag_double(div);
   1253         tv_mod = ktag_double(mod);
   1254         break;
   1255     }
   1256     case K_TEINF:
   1257         if (ttiseinf(tv_n)) {
   1258             klispE_throw_simple(K, "non finite dividend");
   1259             return;
   1260         } else { /* if (ttiseinf(tv_d)) */
   1261             /* The semantics here are unclear, following the general
   1262                guideline of the report that says that if an infinity is 
   1263                involved it should be understand as a limit. In that
   1264                case once the divisor is greater in magnitude than the
   1265                dividend the division stabilizes itself at q = 0; r = n
   1266                if both have the same sign, and q = 1; r = +infinity if
   1267                both have different sign (but in that case !(r < |d|)
   1268                !!) */ 
   1269             /* RATIONALE: if q were 0 we can't accomplish 
   1270                q * d + r = n because q * d is undefined, if q isn't zero
   1271                then, either q*d + r is infinite or undefined so
   1272                there's no good q.  on the other hand if we want 
   1273                n - q*d = r & 0 <= r < d, r can't be infinite because it
   1274                would be equal to d, but q*d is infinite, so there's no
   1275                way out */
   1276             /* throw an exception, until this is resolved */
   1277             /* ASK John */
   1278             klispE_throw_simple(K, "non finite divisor");
   1279             return;
   1280         }
   1281     case K_TIINF:
   1282         if (ttisiinf(tv_n)) {
   1283             klispE_throw_simple(K, "non finite dividend");
   1284             return;
   1285         } else { /* if (ttiseinf(tv_d)) */
   1286             /* The semantics here are unclear, following the general
   1287                guideline of the report that says that if an infinity is 
   1288                involved it should be understand as a limit. In that
   1289                case once the divisor is greater in magnitude than the
   1290                dividend the division stabilizes itself at q = 0; r = n
   1291                if both have the same sign, and q = 1; r = +infinity if
   1292                both have different sign (but in that case !(r < |d|)
   1293                !!) */ 
   1294             /* RATIONALE: if q were 0 we can't accomplish 
   1295                q * d + r = n because q * d is undefined, if q isn't zero
   1296                then, either q*d + r is infinite or undefined so
   1297                there's no good q.  on the other hand if we want 
   1298                n - q*d = r & 0 <= r < d, r can't be infinite because it
   1299                would be equal to d, but q*d is infinite, so there's no
   1300                way out */
   1301             /* throw an exception, until this is resolved */
   1302             /* ASK John */
   1303             klispE_throw_simple(K, "non finite divisor");
   1304             return;
   1305         }
   1306     case K_TRWNPV: { /* no primary value */
   1307         /* ASK John: what happens with undefined & real with no primary values */
   1308         TValue n = ttisrwnpv(tv_n)? tv_n : tv_d;
   1309         if (kcurr_strict_arithp(K)) {					
   1310             klispE_throw_simple_with_irritants(K, "operand has no primary "
   1311                                                "value", 1, n);
   1312             return;
   1313         } else {
   1314             tv_div = KRWNPV;
   1315             tv_mod = KRWNPV;
   1316             break;
   1317         }
   1318     }
   1319     default: 
   1320         klispE_throw_simple(K, "unsupported type");
   1321         return;
   1322     }
   1323 
   1324 
   1325     TValue res;
   1326     if (flags & FDIV_DIV) {
   1327         if (flags & FDIV_MOD) { /* return both div and mod */
   1328             krooted_tvs_push(K, tv_div);
   1329             krooted_tvs_push(K, tv_mod);
   1330             res = klist(K, 2, tv_div, tv_mod);
   1331             krooted_tvs_pop(K);
   1332             krooted_tvs_pop(K);
   1333         } else {
   1334             res = tv_div;
   1335         }
   1336     } else {
   1337         res = tv_mod;
   1338     }
   1339     kapply_cc(K, res);
   1340 }
   1341 
   1342 /* 12.5.10 positive?, negative? */
   1343 /* use ftyped_predp */
   1344 
   1345 /* 12.5.11 odd?, even? */
   1346 /* use ftyped_predp */
   1347 
   1348 /* Helpers for positive?, negative?, odd? & even? */
   1349 /* positive and negative, in kghelpers */
   1350 /* n is finite, integer */
   1351 bool koddp(TValue n) 
   1352 { 
   1353     switch (ttype(n)) {
   1354     case K_TFIXINT:
   1355         return (ivalue(n) & 1) != 0; 
   1356     case K_TBIGINT:
   1357         return kbigint_oddp(n);
   1358     case K_TDOUBLE:
   1359         return fmod(dvalue(n), 2.0) != 0.0;
   1360         /* real with no prim value, complex and undefined should be captured by 
   1361            type predicate */
   1362     default:
   1363         assert(0);
   1364         return false;
   1365     }
   1366 }
   1367 
   1368 bool kevenp(TValue n) 
   1369 { 
   1370     switch (ttype(n)) {
   1371     case K_TFIXINT:
   1372         return (ivalue(n) & 1) == 0; 
   1373     case K_TBIGINT:
   1374         return kbigint_evenp(n);
   1375     case K_TDOUBLE:
   1376         return fmod(dvalue(n), 2.0) == 0.0;
   1377         /* real with no prim value, complex and undefined should be captured by 
   1378            type predicate */
   1379     default:
   1380         assert(0);
   1381         return false;
   1382     }
   1383 }
   1384 
   1385 /* 12.5.12 abs */
   1386 void kabs(klisp_State *K)
   1387 {
   1388     TValue *xparams = K->next_xparams;
   1389     TValue ptree = K->next_value;
   1390     TValue denv = K->next_env;
   1391     klisp_assert(ttisenvironment(K->next_env));
   1392     UNUSED(xparams);
   1393     UNUSED(denv);
   1394 
   1395     bind_1tp(K, ptree, "number", knumberp, n);
   1396 
   1397     TValue res = knum_abs(K, n);
   1398     kapply_cc(K, res);
   1399 }
   1400 
   1401 #define FMIN (true)
   1402 #define FMAX (false)
   1403 
   1404 /* 12.5.13 min, max */
   1405 /* NOTE: this does two passes, one for error checking and one for doing
   1406    the actual work */
   1407 void kmin_max(klisp_State *K)
   1408 {
   1409     TValue *xparams = K->next_xparams;
   1410     TValue ptree = K->next_value;
   1411     TValue denv = K->next_env;
   1412     klisp_assert(ttisenvironment(K->next_env));
   1413     /*
   1414     ** xparams[0]: symbol name
   1415     ** xparams[1]: bool: true min, false max
   1416     */
   1417     UNUSED(denv);
   1418     
   1419     bool minp = bvalue(xparams[1]);
   1420 
   1421     /* cycles are allowed, loop counting pairs */
   1422     int32_t pairs;
   1423     check_typed_list(K, knumberp, true, ptree, &pairs, NULL);
   1424     
   1425     TValue res;
   1426 
   1427     res = minp? KEPINF : KEMINF;
   1428 
   1429     TValue tail = ptree;
   1430     bool (*cmp)(klisp_State *K, TValue, TValue) = minp? knum_ltp : knum_gtp;
   1431 
   1432     while(pairs--) {
   1433         TValue first = kcar(tail);
   1434         tail = kcdr(tail);
   1435 
   1436         if ((*cmp)(K, first, res))
   1437             res = first;
   1438     }
   1439     kapply_cc(K, res);
   1440 }
   1441 
   1442 /* 12.5.14 gcm, lcm */
   1443 void kgcd(klisp_State *K)
   1444 {
   1445     TValue *xparams = K->next_xparams;
   1446     TValue ptree = K->next_value;
   1447     TValue denv = K->next_env;
   1448     klisp_assert(ttisenvironment(K->next_env));
   1449     UNUSED(xparams);
   1450     UNUSED(denv);
   1451     /* cycles are allowed, loop counting pairs */
   1452     int32_t pairs;
   1453     check_typed_list(K, kimp_intp, true, ptree, &pairs, NULL);
   1454 
   1455     TValue res = i2tv(0);
   1456     krooted_vars_push(K, &res);
   1457 
   1458     if (pairs == 0) {
   1459         res = KEPINF; /* report: (gcd) = #e+infinity */
   1460     } else {
   1461         TValue tail = ptree;
   1462         bool seen_finite_non_zero = false; 
   1463         /* res = 0 */
   1464 
   1465         while(pairs--) {
   1466             TValue first = kcar(tail);
   1467             tail = kcdr(tail);
   1468             seen_finite_non_zero |= 
   1469                 (!ttisinf(first) && !kfast_zerop(first));
   1470             res = knum_gcd(K, res, first);
   1471         }
   1472 
   1473         if (!seen_finite_non_zero)
   1474             res = KRWNPV;
   1475     }
   1476 
   1477     krooted_vars_pop(K);
   1478     arith_kapply_cc(K, res);
   1479 }
   1480 
   1481 void klcm(klisp_State *K)
   1482 {
   1483     TValue *xparams = K->next_xparams;
   1484     TValue ptree = K->next_value;
   1485     TValue denv = K->next_env;
   1486     klisp_assert(ttisenvironment(K->next_env));
   1487     UNUSED(xparams);
   1488     UNUSED(denv);
   1489     /* cycles are allowed, loop counting pairs */
   1490     int32_t pairs;
   1491     check_typed_list(K, kimp_intp, true, ptree, &pairs, NULL);
   1492 
   1493     /* report: this will cover the case of (lcm) = 1 */
   1494     TValue res = i2tv(1);
   1495     krooted_vars_push(K, &res);
   1496     
   1497     TValue tail = ptree;
   1498     while(pairs--) {
   1499         TValue first = kcar(tail);
   1500         tail = kcdr(tail);
   1501         /* This will check that neither is zero */
   1502         res = knum_lcm(K, res, first);
   1503     }
   1504 
   1505     krooted_vars_pop(K);
   1506     kapply_cc(K, res);
   1507 }
   1508 
   1509 
   1510 /* 12.6.1 exact?, inexact?, robust?, undefined? */
   1511 /* use fyped_predp */
   1512 
   1513 /* 12.6.2 get-real-internal-bounds, get-real-exact-bounds */
   1514 void kget_real_internal_bounds(klisp_State *K)
   1515 {
   1516     TValue *xparams = K->next_xparams;
   1517     TValue ptree = K->next_value;
   1518     TValue denv = K->next_env;
   1519     klisp_assert(ttisenvironment(K->next_env));
   1520 
   1521     UNUSED(denv);
   1522     UNUSED(xparams);
   1523 
   1524     bind_1tp(K, ptree, "real", krealp, tv_n);
   1525     /* TEMP: do it here directly, for now all inexact objects have
   1526        [-inf, +inf] bounds */
   1527     TValue res;
   1528     if (ttisexact(tv_n)) {
   1529         res = klist(K, 2, tv_n, tv_n);
   1530     } else {
   1531         res = klist(K, 2, KIMINF, KIPINF);
   1532     }
   1533     kapply_cc(K, res);
   1534 }
   1535 
   1536 void kget_real_exact_bounds(klisp_State *K)
   1537 {
   1538     TValue *xparams = K->next_xparams;
   1539     TValue ptree = K->next_value;
   1540     TValue denv = K->next_env;
   1541     klisp_assert(ttisenvironment(K->next_env));
   1542     UNUSED(denv);
   1543     UNUSED(xparams);
   1544 
   1545     bind_1tp(K, ptree, "real", krealp, tv_n);
   1546     /* TEMP: do it here directly, for now all inexact objects have
   1547        [-inf, +inf] bounds, when bounded reals are implemented this
   1548        should take care to round the min towards -inf and the max towards
   1549        +inf when converting to exact */
   1550     TValue res;
   1551     if (ttisexact(tv_n)) {
   1552         res = klist(K, 2, tv_n, tv_n);
   1553     } else {
   1554         res = klist(K, 2, KEMINF, KEPINF);
   1555     }
   1556     kapply_cc(K, res);
   1557 }
   1558 
   1559 /* 12.6.3 get-real-internal-primary, get-real-exact-primary */
   1560 void kget_real_internal_primary(klisp_State *K)
   1561 {
   1562     TValue *xparams = K->next_xparams;
   1563     TValue ptree = K->next_value;
   1564     TValue denv = K->next_env;
   1565     klisp_assert(ttisenvironment(K->next_env));
   1566     UNUSED(denv);
   1567     UNUSED(xparams);
   1568 
   1569     bind_1tp(K, ptree, "real", krealp, tv_n);
   1570     /* TEMP: do it here directly */
   1571     if (ttisrwnpv(tv_n)) {
   1572         klispE_throw_simple_with_irritants(K, "no primary value", 1, tv_n);
   1573         return; 
   1574     } else {
   1575         kapply_cc(K, tv_n);
   1576     }
   1577 }
   1578 
   1579 void kget_real_exact_primary(klisp_State *K)
   1580 {
   1581     TValue *xparams = K->next_xparams;
   1582     TValue ptree = K->next_value;
   1583     TValue denv = K->next_env;
   1584     UNUSED(denv);
   1585     UNUSED(xparams);
   1586 
   1587     klisp_assert(ttisenvironment(K->next_env));
   1588     bind_1tp(K, ptree, "real", krealp, tv_n);
   1589     
   1590     /* NOTE: this handles no primary value errors & exact cases just fine */
   1591     TValue res = kinexact_to_exact(K, tv_n);
   1592     kapply_cc(K, res);
   1593 }
   1594 
   1595 /* 12.6.4 make-inexact */
   1596 void kmake_inexact(klisp_State *K)
   1597 {
   1598     TValue *xparams = K->next_xparams;
   1599     TValue ptree = K->next_value;
   1600     TValue denv = K->next_env;
   1601     klisp_assert(ttisenvironment(K->next_env));
   1602     UNUSED(denv);
   1603     UNUSED(xparams);
   1604 
   1605     bind_3tp(K, ptree, "real", krealp, real1, 
   1606              "real", krealp, real2, "real", krealp, real3);
   1607 
   1608     TValue res;
   1609     UNUSED(real1);
   1610     UNUSED(real3);
   1611     if (ttisinexact(real2)) {
   1612         res = real2;
   1613     } else {
   1614         /* TEMP: for now bounds are ignored */
   1615         /* NOTE: this handles overflow and underflow */
   1616         res = kexact_to_inexact(K, real2);
   1617     }
   1618     kapply_cc(K, res);
   1619 }
   1620 
   1621 /* 12.6.5 real->inexact, real->exact */
   1622 void kreal_to_inexact(klisp_State *K)
   1623 {
   1624     TValue *xparams = K->next_xparams;
   1625     TValue ptree = K->next_value;
   1626     TValue denv = K->next_env;
   1627     klisp_assert(ttisenvironment(K->next_env));
   1628     UNUSED(denv);
   1629     UNUSED(xparams);
   1630 
   1631     bind_1tp(K, ptree, "real", krealp, tv_n);
   1632 
   1633     /* NOTE: this handles overflow and underflow */
   1634     TValue res = kexact_to_inexact(K, tv_n);
   1635     kapply_cc(K, res);
   1636 }
   1637 
   1638 void kreal_to_exact(klisp_State *K)
   1639 {
   1640     TValue *xparams = K->next_xparams;
   1641     TValue ptree = K->next_value;
   1642     TValue denv = K->next_env;
   1643     klisp_assert(ttisenvironment(K->next_env));
   1644     UNUSED(denv);
   1645     UNUSED(xparams);
   1646 
   1647     bind_1tp(K, ptree, "real", krealp, tv_n);
   1648 
   1649     TValue res = kinexact_to_exact(K, tv_n);
   1650     kapply_cc(K, res);
   1651 }
   1652 
   1653 /* 12.6.6 with-strict-arithmetic, get-strict-arithmetic? */
   1654 void kwith_strict_arithmetic(klisp_State *K)
   1655 {
   1656     TValue *xparams = K->next_xparams;
   1657     TValue ptree = K->next_value;
   1658     TValue denv = K->next_env;
   1659     klisp_assert(ttisenvironment(K->next_env));
   1660     UNUSED(xparams);
   1661 
   1662     bind_2tp(K, ptree, "bool", ttisboolean, strictp,
   1663              "combiner", ttiscombiner, comb);
   1664 
   1665     TValue op = kmake_operative(K, do_bind, 1, G(K)->kd_strict_arith_key);
   1666     krooted_tvs_push(K, op);
   1667 
   1668     TValue args = klist(K, 2, strictp, comb);
   1669 
   1670     krooted_tvs_pop(K);
   1671 
   1672     /* even if we call with denv, do_bind calls comb in an empty env */
   1673     /* XXX: what to pass for source info?? */
   1674     ktail_call(K, op, args, denv);
   1675 }
   1676 
   1677 void kget_strict_arithmeticp(klisp_State *K)
   1678 {
   1679     TValue *xparams = K->next_xparams;
   1680     TValue ptree = K->next_value;
   1681     TValue denv = K->next_env;
   1682     klisp_assert(ttisenvironment(K->next_env));
   1683     UNUSED(denv);
   1684     UNUSED(xparams);
   1685 
   1686     check_0p(K, ptree);
   1687 
   1688     /* can access directly, no need to call do_access */
   1689     TValue res = b2tv(kcurr_strict_arithp(K));
   1690     kapply_cc(K, res);
   1691 }
   1692 
   1693 /* 12.8.1 rational? */
   1694 /* uses ftypep */
   1695 
   1696 /* 12.8.2 / */
   1697 void kdivided(klisp_State *K)
   1698 {
   1699     TValue *xparams = K->next_xparams;
   1700     TValue ptree = K->next_value;
   1701     TValue denv = K->next_env;
   1702     klisp_assert(ttisenvironment(K->next_env));
   1703     UNUSED(denv);
   1704     UNUSED(xparams);
   1705     /* cycles are allowed, loop counting pairs */
   1706     int32_t pairs, cpairs;
   1707     
   1708     /* / in kernel (and unlike in scheme) requires at least 2 arguments */
   1709     if (!ttispair(ptree) || !ttispair(kcdr(ptree))) {
   1710         klispE_throw_simple(K, "at least two values are required");
   1711         return;
   1712     } else if (!knumberp(kcar(ptree))) {
   1713         klispE_throw_simple(K, "bad type on first argument (expected number)");
   1714         return;
   1715     }
   1716     TValue first_val = kcar(ptree);
   1717     check_typed_list(K, knumberp, true, kcdr(ptree), &pairs, &cpairs);
   1718     int32_t apairs = pairs - cpairs;
   1719 
   1720     TValue res;
   1721 
   1722     /* first the acyclic part */
   1723     TValue ares = i2tv(1);
   1724     TValue tail = kcdr(ptree);
   1725 
   1726     krooted_vars_push(K, &ares);
   1727 
   1728     while(apairs--) {
   1729         TValue first = kcar(tail);
   1730         tail = kcdr(tail);
   1731         ares = knum_times(K, ares, first);
   1732     }
   1733 
   1734     /* next the cyclic part */
   1735     TValue cres = i2tv(1);
   1736 
   1737     if (cpairs == 0 && !ttisnwnpv(ares)) { /* #undefined or #real */
   1738         /* speed things up if there is no cycle */
   1739         res = ares;
   1740         krooted_vars_pop(K);
   1741     } else {
   1742         bool all_one = true;
   1743         bool all_exact = true;
   1744 
   1745         krooted_vars_push(K, &cres);
   1746         while(cpairs--) {
   1747             TValue first = kcar(tail);
   1748             tail = kcdr(tail);
   1749             all_one = all_one && kfast_onep(first);
   1750             all_exact = all_exact && ttisexact(first);
   1751             cres = knum_times(K, cres, first);
   1752         }
   1753 
   1754         /* think of cres as the product of an infinite series */
   1755         if (ttisnwnpv(ares))
   1756             ; /* do nothing */
   1757         if (kfast_zerop(cres)) 
   1758             ; /* do nothing */
   1759         else if (kpositivep(cres) && knum_ltp(K, cres, i2tv(1))) {
   1760             if (all_exact)
   1761                 cres = i2tv(0);
   1762             else 
   1763                 cres = d2tv(0.0);
   1764         }
   1765         else if (kfast_onep(cres)) {
   1766             if (all_one) {
   1767                 if (all_exact)
   1768                     cres = i2tv(1);
   1769                 else
   1770                     cres = d2tv(1.0);
   1771             } else 
   1772                 cres = KRWNPV;
   1773         } else if (knum_gtp(K, cres, i2tv(1))) {
   1774             /* ASK JOHN: this is as per the report, but maybe we should check
   1775                that all elements are positive... */
   1776             cres = all_exact? KEPINF : KIPINF;
   1777         } else
   1778             cres = KRWNPV;
   1779 
   1780         /* this will throw error if necessary on no primary value */
   1781         res = knum_times(K, ares, cres);
   1782         krooted_vars_pop(K);
   1783         krooted_vars_pop(K);
   1784     } 
   1785 
   1786     /* now divide first value by the product of all the elements in the list */
   1787     krooted_tvs_push(K, res);
   1788     res = knum_divided(K, first_val, res);
   1789     krooted_tvs_pop(K);
   1790 
   1791     kapply_cc(K, res);
   1792 }
   1793 
   1794 /* 12.8.3 numerator, denominator */
   1795 void knumerator(klisp_State *K)
   1796 {
   1797     TValue *xparams = K->next_xparams;
   1798     TValue ptree = K->next_value;
   1799     TValue denv = K->next_env;
   1800     klisp_assert(ttisenvironment(K->next_env));
   1801     UNUSED(denv);
   1802     UNUSED(xparams);
   1803     
   1804     bind_1tp(K, ptree, "rational", krationalp, n);
   1805 
   1806     TValue res = knum_numerator(K, n);
   1807     kapply_cc(K, res);
   1808 }
   1809 
   1810 void kdenominator(klisp_State *K)
   1811 {
   1812     TValue *xparams = K->next_xparams;
   1813     TValue ptree = K->next_value;
   1814     TValue denv = K->next_env;
   1815     klisp_assert(ttisenvironment(K->next_env));
   1816     UNUSED(denv);
   1817     UNUSED(xparams);
   1818     
   1819     bind_1tp(K, ptree, "rational", krationalp, n);
   1820 
   1821     TValue res = knum_denominator(K, n);
   1822     kapply_cc(K, res);
   1823 }
   1824 
   1825 /* 12.8.4 floor, ceiling, truncate, round */
   1826 void kreal_to_integer(klisp_State *K)
   1827 {
   1828     TValue *xparams = K->next_xparams;
   1829     TValue ptree = K->next_value;
   1830     TValue denv = K->next_env;
   1831     klisp_assert(ttisenvironment(K->next_env));
   1832     /*
   1833     ** xparams[0]: symbol name
   1834     ** xparams[1]: bool: true min, false max
   1835     */
   1836     UNUSED(denv);
   1837     kround_mode mode = (kround_mode) ivalue(xparams[1]);
   1838     
   1839     bind_1tp(K, ptree, "real", krealp, n);
   1840 
   1841     TValue res = knum_real_to_integer(K, n, mode);
   1842     kapply_cc(K, res);
   1843 }
   1844 
   1845 /* 12.8.5 rationalize, simplest-rational */
   1846 void krationalize(klisp_State *K)
   1847 {
   1848     TValue *xparams = K->next_xparams;
   1849     TValue ptree = K->next_value;
   1850     TValue denv = K->next_env;
   1851     klisp_assert(ttisenvironment(K->next_env));
   1852     UNUSED(denv);
   1853     UNUSED(xparams);
   1854 
   1855     bind_2tp(K, ptree, "real", krealp, n1, 
   1856              "real", krealp, n2);
   1857 
   1858     TValue res = knum_rationalize(K, n1, n2);
   1859     kapply_cc(K, res);
   1860 }
   1861 
   1862 void ksimplest_rational(klisp_State *K)
   1863 {
   1864     TValue *xparams = K->next_xparams;
   1865     TValue ptree = K->next_value;
   1866     TValue denv = K->next_env;
   1867     klisp_assert(ttisenvironment(K->next_env));
   1868     UNUSED(denv);
   1869     UNUSED(xparams);
   1870 
   1871     bind_2tp(K, ptree, "real", krealp, n1, 
   1872              "real", krealp, n2);
   1873 
   1874     TValue res = knum_simplest_rational(K, n1, n2);
   1875     kapply_cc(K, res);
   1876 }
   1877 
   1878 void kexp(klisp_State *K)
   1879 {
   1880     TValue *xparams = K->next_xparams;
   1881     TValue ptree = K->next_value;
   1882     TValue denv = K->next_env;
   1883     klisp_assert(ttisenvironment(K->next_env));
   1884     UNUSED(denv);
   1885     UNUSED(xparams);
   1886 
   1887     bind_1tp(K, ptree, "number", knumberp, n);
   1888 
   1889     /* TEMP: do it inline for now */
   1890     TValue res = i2tv(0);
   1891     switch(ttype(n)) {
   1892     case K_TFIXINT: 
   1893     case K_TBIGINT:
   1894     case K_TBIGRAT:
   1895         /* for now, all go to double */
   1896         n = kexact_to_inexact(K, n); /* no need to root it */
   1897         /* fall through */
   1898     case K_TDOUBLE: {
   1899         double d = exp(dvalue(n));
   1900         res = ktag_double(d);
   1901         break;
   1902     }
   1903     case K_TEINF: /* in any case return inexact result (e is inexact) */
   1904     case K_TIINF:
   1905         res = kpositivep(n)? KIPINF : d2tv(0.0);
   1906         break;
   1907     case K_TRWNPV:
   1908     case K_TUNDEFINED:
   1909         klispE_throw_simple_with_irritants(K, "no primary value", 1, n);
   1910         return;
   1911         /* complex and undefined should be captured by type predicate */
   1912     default:
   1913         klispE_throw_simple(K, "unsupported type");
   1914         return;
   1915     }
   1916     kapply_cc(K, res);
   1917 }
   1918 
   1919 void klog(klisp_State *K)
   1920 {
   1921     TValue *xparams = K->next_xparams;
   1922     TValue ptree = K->next_value;
   1923     TValue denv = K->next_env;
   1924     klisp_assert(ttisenvironment(K->next_env));
   1925     UNUSED(denv);
   1926     UNUSED(xparams);
   1927 
   1928     bind_1tp(K, ptree, "number", knumberp, n);
   1929 
   1930     /* ASK John: error or no primary value, or undefined */
   1931     if (kfast_zerop(n)) {
   1932         klispE_throw_simple_with_irritants(K, "zero argument", 1, n);
   1933         return;
   1934     } else if (knegativep(n)) {
   1935         klispE_throw_simple_with_irritants(K, "negative argument", 1, n);
   1936         return;
   1937     }
   1938 
   1939     /* TEMP: do it inline for now */
   1940     TValue res = i2tv(0);
   1941     switch(ttype(n)) {
   1942     case K_TFIXINT: 
   1943     case K_TBIGINT:
   1944     case K_TBIGRAT:
   1945         /* for now, all go to double */
   1946         n = kexact_to_inexact(K, n); /* no need to root it */
   1947         /* fall through */
   1948     case K_TDOUBLE: {
   1949         double d = log(dvalue(n));
   1950         res = ktag_double(d);
   1951         break;
   1952     }
   1953     case K_TEINF: /* in any case return inexact result (e is inexact) */
   1954     case K_TIINF:
   1955         /* is this ok? */
   1956         res = KIPINF;
   1957         break;
   1958     case K_TRWNPV:
   1959     case K_TUNDEFINED:
   1960         klispE_throw_simple_with_irritants(K, "no primary value", 1, n);
   1961         return;
   1962         /* complex and undefined should be captured by type predicate */
   1963     default:
   1964         klispE_throw_simple(K, "unsupported type");
   1965         return;
   1966     }
   1967     kapply_cc(K, res);
   1968 }
   1969 
   1970 void ktrig(klisp_State *K)
   1971 {
   1972     TValue *xparams = K->next_xparams;
   1973     TValue ptree = K->next_value;
   1974     TValue denv = K->next_env;
   1975     klisp_assert(ttisenvironment(K->next_env));
   1976     UNUSED(denv);
   1977     /*
   1978     ** xparams[0]: trig function
   1979     */
   1980     double (*fn)(double) = pvalue(xparams[0]);
   1981 
   1982     bind_1tp(K, ptree, "number", knumberp, n);
   1983 
   1984     /* TEMP: do it inline for now */
   1985     TValue res = i2tv(0);
   1986     switch(ttype(n)) {
   1987     case K_TFIXINT: 
   1988     case K_TBIGINT:
   1989     case K_TBIGRAT:
   1990         /* for now, all go to double */
   1991         n = kexact_to_inexact(K, n); /* no need to root it */
   1992         /* fall through */
   1993     case K_TDOUBLE: {
   1994         double d = (*fn)(dvalue(n));
   1995         res = ktag_double(d);
   1996         break;
   1997     }
   1998     case K_TEINF: 
   1999     case K_TIINF:
   2000         /* is this ok? */
   2001         res = KRWNPV;
   2002         break;
   2003     case K_TRWNPV:
   2004     case K_TUNDEFINED:
   2005         klispE_throw_simple_with_irritants(K, "no primary value", 1, n);
   2006         return;
   2007     default:
   2008         klispE_throw_simple(K, "unsupported type");
   2009         return;
   2010     }
   2011     arith_kapply_cc(K, res);
   2012 }
   2013 
   2014 void katrig(klisp_State *K)
   2015 {
   2016     TValue *xparams = K->next_xparams;
   2017     TValue ptree = K->next_value;
   2018     TValue denv = K->next_env;
   2019     klisp_assert(ttisenvironment(K->next_env));
   2020     UNUSED(denv);
   2021     /*
   2022     ** xparams[0]: trig function
   2023     */
   2024     double (*fn)(double) = pvalue(xparams[0]);
   2025 
   2026     bind_1tp(K, ptree, "number", knumberp, n);
   2027 
   2028     /* TEMP: do it inline for now */
   2029     TValue res = i2tv(0);
   2030     switch(ttype(n)) {
   2031     case K_TFIXINT: 
   2032     case K_TBIGINT:
   2033     case K_TBIGRAT:
   2034         /* for now, all go to double */
   2035         n = kexact_to_inexact(K, n); /* no need to root it */
   2036         /* fall through */
   2037     case K_TDOUBLE: {
   2038         double d = dvalue(n);
   2039         if (d >= -1.0 && d <= 1.0) {
   2040             d = (*fn)(dvalue(n));
   2041             res = ktag_double(d);
   2042         } else {
   2043             res = KUNDEF; /* ASK John: is this ok, or should throw error? */
   2044         }
   2045         break;
   2046     }
   2047     case K_TEINF: 
   2048     case K_TIINF:
   2049         /* ASK John: is this ok? */
   2050         res = KRWNPV;
   2051         break;
   2052     case K_TRWNPV:
   2053     case K_TUNDEFINED:
   2054         klispE_throw_simple_with_irritants(K, "no primary value", 1, n);
   2055         return;
   2056     default:
   2057         klispE_throw_simple(K, "unsupported type");
   2058         return;
   2059     }
   2060     arith_kapply_cc(K, res);
   2061 }
   2062 
   2063 void katan(klisp_State *K)
   2064 {
   2065     TValue *xparams = K->next_xparams;
   2066     TValue ptree = K->next_value;
   2067     TValue denv = K->next_env;
   2068     klisp_assert(ttisenvironment(K->next_env));
   2069     UNUSED(denv);
   2070     UNUSED(xparams);
   2071 
   2072     bind_al1tp(K, ptree, "number", knumberp, n1, rest);
   2073     bool two_params;
   2074     TValue n2;
   2075     if (ttisnil(rest)) {
   2076         two_params = false;
   2077         n2 = n1;
   2078     } else {
   2079         two_params = true;
   2080         if (!ttispair(rest) || !ttisnil(kcdr(rest))) {
   2081             klispE_throw_simple(K, "Bad ptree structure (in optional "
   2082                                 "argument)");
   2083             return;
   2084         } else if (!ttisnumber(kcar(rest))) {
   2085             klispE_throw_simple(K, "Bad type on optional argument "
   2086                                 "(expected number)");
   2087             return;
   2088         } else {
   2089             n2 = kcar(rest);
   2090             kensure_same_exactness(K, n1, n2);
   2091         }
   2092     }
   2093 
   2094     /* TEMP: do it inline for now */
   2095     TValue res = i2tv(0);
   2096     switch(max_ttype(n1, n2)) {
   2097     case K_TFIXINT: 
   2098     case K_TBIGINT:
   2099     case K_TBIGRAT:
   2100         /* for now, all go to double */
   2101         n1 = kexact_to_inexact(K, n1); /* no need to root it */
   2102         if (two_params)
   2103             n2 = kexact_to_inexact(K, n2); /* no need to root it */
   2104         /* fall through */
   2105     case K_TDOUBLE: {
   2106         double d1 = dvalue(n1);
   2107         if (two_params) {
   2108             double d2 = dvalue(n2);
   2109             d1 = atan2(d1, d2);
   2110         } else {
   2111             d1 = atan(d1);
   2112         }
   2113         res = ktag_double(d1);
   2114         break;
   2115     }
   2116     case K_TEINF: 
   2117     case K_TIINF:
   2118         /* ASK John: is this ok? */
   2119         if (two_params) {
   2120             if (kfinitep(n1)) {
   2121                 res = ktag_double(0.0);
   2122             } else if (!kfinitep(n2)) {
   2123                 klispE_throw_simple_with_irritants(K, "infinite divisor & "
   2124                                                    "dividend", 2, n1, n2);
   2125                 return;
   2126             } else {
   2127                 /* XXX either pi/2 or -pi/2, but we don't have the constant */
   2128                 double d = knum_same_signp(K, n1, n2)? atan(INFINITY) : 
   2129                     atan(-INFINITY);
   2130                 res = ktag_double(d);
   2131             }
   2132         } else {
   2133             /* XXX either pi/2 or -pi/2, but we don't have the constant */
   2134             double d = kpositivep(n1)? atan(INFINITY) : atan(-INFINITY);
   2135             res = ktag_double(d);
   2136         }
   2137         break;
   2138     case K_TRWNPV:
   2139     case K_TUNDEFINED:
   2140         if (two_params) {
   2141             klispE_throw_simple_with_irritants(K, "no primary value", 2, 
   2142                                                n1, n2);
   2143         } else {
   2144             klispE_throw_simple_with_irritants(K, "no primary value", 1, n1);
   2145         }
   2146         return;
   2147     default:
   2148         klispE_throw_simple(K, "unsupported type");
   2149         return;
   2150     }
   2151     arith_kapply_cc(K, res);
   2152 }
   2153 
   2154 void ksqrt(klisp_State *K)
   2155 {
   2156     TValue *xparams = K->next_xparams;
   2157     TValue ptree = K->next_value;
   2158     TValue denv = K->next_env;
   2159     klisp_assert(ttisenvironment(K->next_env));
   2160     UNUSED(denv);
   2161     UNUSED(xparams);
   2162 
   2163     bind_1tp(K, ptree, "number", knumberp, n);
   2164 
   2165     /* TEMP: do it inline for now */
   2166     TValue res = i2tv(0);
   2167     switch(ttype(n)) {
   2168     case K_TFIXINT: 
   2169     case K_TBIGINT:
   2170     case K_TBIGRAT:
   2171         /* TEMP: for now, all go to double */
   2172         n = kexact_to_inexact(K, n); /* no need to root it */
   2173         /* fall through */
   2174     case K_TDOUBLE: {
   2175         double d = dvalue(n);
   2176         if (d < 0.0)
   2177             res = KUNDEF;  /* ASK John: is this ok, or should throw error? */
   2178         else {
   2179             d = sqrt(d);
   2180             res = ktag_double(d);
   2181         }
   2182         break;
   2183     }
   2184     case K_TEINF: 
   2185     case K_TIINF:
   2186         res = knegativep(n)? KUNDEF : KIPINF;
   2187         break;
   2188     case K_TRWNPV:
   2189     case K_TUNDEFINED:
   2190         klispE_throw_simple_with_irritants(K, "no primary value", 1, n);
   2191         return;
   2192     default:
   2193         klispE_throw_simple(K, "unsupported type");
   2194         return;
   2195     }
   2196     arith_kapply_cc(K, res);
   2197 }
   2198 
   2199 void kexpt(klisp_State *K)
   2200 {
   2201     TValue *xparams = K->next_xparams;
   2202     TValue ptree = K->next_value;
   2203     TValue denv = K->next_env;
   2204     klisp_assert(ttisenvironment(K->next_env));
   2205     UNUSED(denv);
   2206     UNUSED(xparams);
   2207 
   2208     bind_2tp(K, ptree, "number", knumberp, n1,
   2209              "number", knumberp, n2);
   2210 
   2211     kensure_same_exactness(K, n1, n2);
   2212 
   2213     /* TEMP: do it inline for now */
   2214     TValue res = i2tv(0);
   2215     switch(max_ttype(n1, n2)) {
   2216     case K_TFIXINT: 
   2217     case K_TBIGINT:
   2218     case K_TBIGRAT:
   2219         /* TEMP: for now, all go to double */
   2220         n1 = kexact_to_inexact(K, n1); /* no need to root it */
   2221         n2 = kexact_to_inexact(K, n2); /* no need to root it */
   2222         /* fall through */
   2223     case K_TDOUBLE: {
   2224         double d1 = dvalue(n1);
   2225         double d2 = dvalue(n2);
   2226         d1 = pow(d1, d2);
   2227         res = ktag_double(d1);
   2228         break;
   2229     }
   2230     case K_TEINF: 
   2231     case K_TIINF:
   2232         if (ttisinf(n1) && ttisinf(n2)) {
   2233             if (knegativep(n1) && knegativep(n2))
   2234                 res = d2tv(0.0);
   2235             else if (knegativep(n1) || knegativep(n2))
   2236                 res = KUNDEF; /* ASK John: is this ok? */
   2237             else 
   2238                 res = KIPINF;
   2239         } else if (ttisinf(n1)) {
   2240             if (knegativep(n1)) {
   2241                 if (knegativep(n2))
   2242                     res = d2tv(0.0);
   2243                 else {
   2244                     TValue num = knum_numerator(K, n2);
   2245                     krooted_tvs_push(K, num);
   2246                     res = kevenp(num)? KIPINF : KIMINF;
   2247                     krooted_tvs_pop(K);
   2248                 }
   2249             } else {
   2250                 res = KIPINF;
   2251             }
   2252         } else { /* ttisinf(n2) */
   2253             if (knegativep(n2))
   2254                 res = d2tv(0.0);
   2255             else if (knegativep(n1))
   2256                 res = KUNDEF; /* ASK John: is this ok? */
   2257             else 
   2258                 res = KIPINF;
   2259         }
   2260         break;
   2261     case K_TRWNPV:
   2262     case K_TUNDEFINED:
   2263         klispE_throw_simple_with_irritants(K, "no primary value", 2, 
   2264                                            n1, n2);
   2265         return;
   2266     default:
   2267         klispE_throw_simple(K, "unsupported type");
   2268         return;
   2269     }
   2270     arith_kapply_cc(K, res);
   2271 }
   2272 
   2273 /* Number<->String conversion */
   2274 void number_to_string(klisp_State *K)
   2275 {
   2276     /* MAYBE this code could be factored out and used in kwrite too, 
   2277        but maybe it's too much allocation for kwrite in the simpler cases */
   2278     TValue *xparams = K->next_xparams;
   2279     TValue ptree = K->next_value;
   2280     TValue denv = K->next_env;
   2281     klisp_assert(ttisenvironment(K->next_env));
   2282     UNUSED(denv);
   2283     UNUSED(xparams);
   2284 
   2285     bind_al1tp(K, ptree, "number", knumberp, obj, maybe_radix);
   2286     int radix = 10;
   2287     if (get_opt_tpar(K, maybe_radix, "radix (2, 8, 10, or 16)", ttisradix))
   2288         radix = ivalue(maybe_radix); 
   2289 
   2290     char small_buf[64]; /* for fixints */
   2291     TValue buf_str = G(K)->empty_string; /* for bigrats, bigints and doubles */
   2292     krooted_vars_push(K, &buf_str);
   2293     char *buf;
   2294 
   2295     switch(ttype(obj)) {
   2296     case K_TFIXINT: {
   2297         /* can't use snprintf here... there's no support for binary,
   2298            so just do by hand */
   2299         uint32_t value;
   2300         /* convert to unsigned to write */
   2301         value = (uint32_t) ((ivalue(obj) < 0)? 
   2302                             -((int64_t) ivalue(obj)) :
   2303                             ivalue(obj));
   2304         char *digits = "0123456789abcdef";
   2305         /* write backwards so we don't have to reverse the buffer */
   2306         buf = small_buf + sizeof(small_buf) - 1;
   2307         *buf-- = '\0';
   2308         do {
   2309             *buf-- = digits[value % radix];
   2310             value /= radix;
   2311         } while(value > 0); /* with the guard down it works for zero too */
   2312 
   2313         /* only put the sign if negative, 
   2314            then correct the pointer to the first char */
   2315         if (ivalue(obj) < 0)
   2316             *buf = '-';
   2317         else 
   2318             ++buf;
   2319         break;
   2320     }
   2321     case K_TBIGINT: {
   2322         int32_t size = kbigint_print_size(obj, radix); 
   2323         /* here we are using 1 byte extra, because size already includes
   2324            1 for the terminator, but better be safe than sorry */
   2325         buf_str = kstring_new_s(K, size);
   2326         buf = kstring_buf(buf_str);
   2327         kbigint_print_string(K, obj, radix, buf, size);
   2328         /* the string will be copied and trimmed later, 
   2329            because print_size may overestimate */
   2330         break;
   2331     }
   2332     case K_TBIGRAT: {
   2333         int32_t size = kbigrat_print_size(obj, radix); 
   2334         /* here we are using 1 byte extra, because size already includes
   2335            1 for the terminator, but better be safe than sorry */
   2336         buf_str = kstring_new_s(K, size);
   2337         buf = kstring_buf(buf_str);
   2338         kbigrat_print_string(K, obj, radix, buf, size);
   2339         /* the string will be copied and trimmed later, 
   2340            because print_size may overestimate */
   2341         break;
   2342     }
   2343     case K_TEINF:
   2344         buf = tv_equal(obj, KEPINF)? "#e+infinity" : "#e-infinity";
   2345         break;
   2346     case K_TIINF:
   2347         buf = tv_equal(obj, KIPINF)? "#i+infinity" : "#i-infinity";
   2348         break;
   2349     case K_TDOUBLE: {
   2350         if (radix != 10) {
   2351             /* only radix 10 is supported for inexact numbers 
   2352                see rationale in the report (technically they could be 
   2353                printed without a decimal point, like fractions, but...*/
   2354             klispE_throw_simple_with_irritants(K, "radix != 10 with inexact "
   2355                                                "number", 2, obj,maybe_radix);
   2356             return;
   2357         }
   2358         /* radix is always 10 */
   2359         int32_t size = kdouble_print_size(obj); 
   2360         /* here we are using 1 byte extra, because size already includes
   2361            1 for the terminator, but better be safe than sorry */
   2362         buf_str = kstring_new_s(K, size);
   2363         buf = kstring_buf(buf_str);
   2364         kdouble_print_string(K, obj, buf, size);
   2365         /* the string will be copied and trimmed later, 
   2366            because print_size may overestimate */
   2367         break;
   2368     }
   2369     case K_TRWNPV:
   2370         buf = "#real";
   2371         break;
   2372     case K_TUNDEFINED:
   2373         buf = "#undefined";
   2374         break;
   2375     default:
   2376         /* shouldn't happen */
   2377         abort();
   2378     }
   2379 
   2380     TValue str = kstring_new_b(K, buf);
   2381     krooted_vars_pop(K);
   2382     kapply_cc(K, str);
   2383 }
   2384 
   2385 struct kspecial_number {
   2386     const char *ext_rep; /* downcase external representation */
   2387     TValue obj;
   2388 } kspecial_numbers[] = { { "#e+infinity", KEPINF_ },
   2389                          { "#e-infinity", KEMINF_ },
   2390                          { "#i+infinity", KIPINF_ },
   2391                          { "#i-infinity", KIMINF_ },
   2392                          { "#real", KRWNPV_ },
   2393                          { "#undefined", KUNDEF_ }
   2394 };
   2395 
   2396 /* N.B. If case insignificance is removed, check here too!
   2397    This will happily accept exactness and radix arguments in both cases
   2398    (but not the names of special numbers) */
   2399 void string_to_number(klisp_State *K)
   2400 {
   2401     /* MAYBE try to unify with ktoken */
   2402 
   2403     TValue *xparams = K->next_xparams;
   2404     TValue ptree = K->next_value;
   2405     TValue denv = K->next_env;
   2406     klisp_assert(ttisenvironment(K->next_env));
   2407     UNUSED(denv);
   2408     UNUSED(xparams);
   2409 
   2410     bind_al1tp(K, ptree, "string", ttisstring, str, maybe_radix);
   2411     int radix = 10;
   2412     if (get_opt_tpar(K, maybe_radix, "radix (2, 8, 10, or 16)", ttisradix))
   2413         radix = ivalue(maybe_radix); 
   2414 
   2415     /* track length to throw better error msgs */
   2416     char *buf = kstring_buf(str);
   2417     int32_t len = kstring_size(str);
   2418 
   2419     /* if at some point we reach the end of the string
   2420        the char will be '\0' and will fail all tests,
   2421        so there is no need to test the length explicitly */
   2422     bool has_exactp = false;
   2423     bool exactp = false; /* the default exactness will depend on the format */
   2424     bool has_radixp = false;
   2425 
   2426     TValue res = KINERT;
   2427     size_t snum_size = sizeof(kspecial_numbers) / 
   2428         sizeof(struct kspecial_number);
   2429     for (int i = 0; i < snum_size; i++) {
   2430         struct kspecial_number number = kspecial_numbers[i];
   2431         /* NOTE: must check type because buf may contain embedded '\0's */
   2432         if (len == strlen(number.ext_rep) &&
   2433             strcmp(number.ext_rep, buf) == 0) {
   2434             res = number.obj; 
   2435             break;
   2436         }
   2437     }
   2438     if (ttisinert(res)) {
   2439         /* number wasn't a special number */
   2440         while (*buf == '#') {
   2441             switch(*++buf) {
   2442             case 'e': case 'E': case 'i': case 'I':
   2443                 if (has_exactp) {
   2444                     klispE_throw_simple_with_irritants(
   2445                         K, "two exactness prefixes", 1, str);
   2446                     return;
   2447                 }
   2448                 has_exactp = true;
   2449                 exactp = (*buf == 'e');
   2450                 ++buf;
   2451                 break;
   2452             case 'b': case 'B': radix = 2; goto RADIX;
   2453             case 'o': case 'O': radix = 8; goto RADIX;
   2454             case 'd': case 'D': radix = 10; goto RADIX;
   2455             case 'x': case 'X': radix = 16; goto RADIX;
   2456             RADIX: 
   2457                 if (has_radixp) {
   2458                     klispE_throw_simple_with_irritants(
   2459                         K, "two radix prefixes", 1, str);
   2460                     return;
   2461                 }
   2462                 has_radixp = true;
   2463                 ++buf;
   2464                 break;
   2465             default:
   2466                 klispE_throw_simple_with_irritants(K, "unexpected char "
   2467                                                    "after #", 1, str);
   2468                 return;
   2469             }
   2470         }
   2471 
   2472         if (radix == 10) {
   2473             /* only allow decimals with radix 10 */
   2474             bool decimalp = false;
   2475             if (!krational_read_decimal(K, buf, radix, &res, NULL, &decimalp)) {
   2476                 klispE_throw_simple_with_irritants(K, "Bad format", 1, str);
   2477                 return;
   2478             }
   2479             if (decimalp && !has_exactp) {
   2480                 /* handle decimal format as an explicit #i */
   2481                 has_exactp = true;
   2482                 exactp = false;
   2483             }
   2484         } else {
   2485             if (!krational_read(K, buf, radix, &res, NULL)) {
   2486                 klispE_throw_simple_with_irritants(K, "Bad format", 1, str);
   2487                 return;
   2488             }
   2489         }
   2490     
   2491         if (has_exactp && !exactp) {
   2492             krooted_tvs_push(K, res);
   2493             res = kexact_to_inexact(K, res);
   2494             krooted_tvs_pop(K);
   2495         }
   2496     }
   2497     kapply_cc(K, res);
   2498 }
   2499 
   2500 /* init ground */
   2501 void kinit_numbers_ground_env(klisp_State *K)
   2502 {
   2503     TValue ground_env = G(K)->ground_env;
   2504     TValue symbol, value;
   2505 
   2506     /* No complex or bounded reals for now */
   2507     /* 12.5.1 number?, finite?, integer? */
   2508     add_applicative(K, ground_env, "number?", ftypep, 2, symbol, 
   2509                     p2tv(knumberp));
   2510     add_applicative(K, ground_env, "finite?", ftyped_predp, 3, symbol, 
   2511                     p2tv(knumber_wpvp), p2tv(kfinitep));
   2512     add_applicative(K, ground_env, "integer?", ftypep, 2, symbol, 
   2513                     p2tv(kintegerp));
   2514     /* 12.5.? exact-integer? */
   2515     add_applicative(K, ground_env, "exact-integer?", ftypep, 2, symbol, 
   2516                     p2tv(keintegerp));
   2517     /* 12.5.? u8? */
   2518     add_applicative(K, ground_env, "u8?", ftypep, 2, symbol, 
   2519                     p2tv(ku8p));
   2520     /* 12.5.2 =? */
   2521     add_applicative(K, ground_env, "=?", ftyped_kbpredp, 3,
   2522                     symbol, p2tv(knumber_wpvp), p2tv(knum_eqp));
   2523     /* 12.5.3 <?, <=?, >?, >=? */
   2524     add_applicative(K, ground_env, "<?", ftyped_kbpredp, 3,
   2525                     symbol, p2tv(kreal_wpvp), p2tv(knum_ltp));
   2526     add_applicative(K, ground_env, "<=?", ftyped_kbpredp, 3,
   2527                     symbol, p2tv(kreal_wpvp),  p2tv(knum_lep));
   2528     add_applicative(K, ground_env, ">?", ftyped_kbpredp, 3,
   2529                     symbol, p2tv(kreal_wpvp), p2tv(knum_gtp));
   2530     add_applicative(K, ground_env, ">=?", ftyped_kbpredp, 3,
   2531                     symbol, p2tv(kreal_wpvp), p2tv(knum_gep));
   2532     /* 12.5.4 + */
   2533     add_applicative(K, ground_env, "+", kplus, 0);
   2534     /* 12.5.5 * */
   2535     add_applicative(K, ground_env, "*", ktimes, 0);
   2536     /* 12.5.6 - */
   2537     add_applicative(K, ground_env, "-", kminus, 0);
   2538     /* 12.5.7 zero? */
   2539     add_applicative(K, ground_env, "zero?", ftyped_predp, 3, symbol, 
   2540                     p2tv(knumber_wpvp), p2tv(kzerop));
   2541     /* 12.5.8 div, mod, div-and-mod */
   2542     add_applicative(K, ground_env, "div", kdiv_mod, 2, symbol, 
   2543                     i2tv(FDIV_DIV));
   2544     add_applicative(K, ground_env, "mod", kdiv_mod, 2, symbol, 
   2545                     i2tv(FDIV_MOD));
   2546     add_applicative(K, ground_env, "div-and-mod", kdiv_mod, 2, symbol, 
   2547                     i2tv(FDIV_DIV | FDIV_MOD));
   2548     /* 12.5.9 div0, mod0, div0-and-mod0 */
   2549     add_applicative(K, ground_env, "div0", kdiv_mod, 2, symbol, 
   2550                     i2tv(FDIV_ZERO | FDIV_DIV));
   2551     add_applicative(K, ground_env, "mod0", kdiv_mod, 2, symbol, 
   2552                     i2tv(FDIV_ZERO | FDIV_MOD));
   2553     add_applicative(K, ground_env, "div0-and-mod0", kdiv_mod, 2, symbol, 
   2554                     i2tv(FDIV_ZERO | FDIV_DIV | FDIV_MOD));
   2555     /* 12.5.10 positive?, negative? */
   2556     add_applicative(K, ground_env, "positive?", ftyped_predp, 3, symbol, 
   2557                     p2tv(kreal_wpvp), p2tv(kpositivep));
   2558     add_applicative(K, ground_env, "negative?", ftyped_predp, 3, symbol, 
   2559                     p2tv(kreal_wpvp), p2tv(knegativep));
   2560     /* 12.5.11 odd?, even? */
   2561     add_applicative(K, ground_env, "odd?", ftyped_predp, 3, symbol, 
   2562                     p2tv(kintegerp), p2tv(koddp));
   2563     add_applicative(K, ground_env, "even?", ftyped_predp, 3, symbol, 
   2564                     p2tv(kintegerp), p2tv(kevenp));
   2565     /* 12.5.12 abs */
   2566     add_applicative(K, ground_env, "abs", kabs, 0);
   2567     /* 12.5.13 min, max */
   2568     add_applicative(K, ground_env, "min", kmin_max, 2, symbol, b2tv(FMIN));
   2569     add_applicative(K, ground_env, "max", kmin_max, 2, symbol, b2tv(FMAX));
   2570     /* 12.5.14 gcd, lcm */
   2571     add_applicative(K, ground_env, "gcd", kgcd, 0);
   2572     add_applicative(K, ground_env, "lcm", klcm, 0);
   2573     /* 12.6.1 exact?, inexact?, robust?, undefined? */
   2574     add_applicative(K, ground_env, "exact?", ftyped_predp, 3, symbol, 
   2575                     p2tv(knumberp), p2tv(kexactp));
   2576     add_applicative(K, ground_env, "inexact?", ftyped_predp, 3, symbol, 
   2577                     p2tv(knumberp), p2tv(kinexactp));
   2578     add_applicative(K, ground_env, "robust?", ftyped_predp, 3, symbol, 
   2579                     p2tv(knumberp), p2tv(krobustp));
   2580     add_applicative(K, ground_env, "undefined?", ftyped_predp, 3, symbol, 
   2581                     p2tv(knumberp), p2tv(kundefinedp));
   2582     /* 12.6.2 get-real-internal-bounds, get-real-exact-bounds */
   2583     add_applicative(K, ground_env, "get-real-internal-bounds", 
   2584                     kget_real_internal_bounds, 0);
   2585     add_applicative(K, ground_env, "get-real-exact-bounds", 
   2586                     kget_real_exact_bounds, 0);
   2587     /* 12.6.3 get-real-internal-primary, get-real-exact-primary */
   2588     add_applicative(K, ground_env, "get-real-internal-primary", 
   2589                     kget_real_internal_primary, 0);
   2590     add_applicative(K, ground_env, "get-real-exact-primary", 
   2591                     kget_real_exact_primary, 0);
   2592     /* 12.6.4 make-inexact */
   2593     add_applicative(K, ground_env, "make-inexact", kmake_inexact, 0);
   2594     /* 12.6.5 real->inexact, real->exact */
   2595     add_applicative(K, ground_env, "real->inexact", kreal_to_inexact, 0);
   2596     add_applicative(K, ground_env, "real->exact", kreal_to_exact, 0);
   2597     /* 12.6.6 with-strict-arithmetic, get-strict-arithmetic? */
   2598     add_applicative(K, ground_env, "with-strict-arithmetic", 
   2599                     kwith_strict_arithmetic, 0);
   2600     add_applicative(K, ground_env, "get-strict-arithmetic?", 
   2601                     kget_strict_arithmeticp, 0);
   2602     /* 12.8.1 rational? */
   2603     add_applicative(K, ground_env, "rational?", ftypep, 2, symbol, 
   2604                     p2tv(krationalp));
   2605     /* 12.8.2 / */
   2606     add_applicative(K, ground_env, "/", kdivided, 0);
   2607     /* 12.8.3 numerator, denominator */
   2608     add_applicative(K, ground_env, "numerator", knumerator, 0);
   2609     add_applicative(K, ground_env, "denominator", kdenominator, 0);
   2610     /* 12.8.4 floor, ceiling, truncate, round */
   2611     add_applicative(K, ground_env, "floor", kreal_to_integer, 2,
   2612                     symbol, i2tv((int32_t) K_FLOOR));
   2613     add_applicative(K, ground_env, "ceiling", kreal_to_integer, 2,
   2614                     symbol, i2tv((int32_t) K_CEILING));
   2615     add_applicative(K, ground_env, "truncate", kreal_to_integer, 2,
   2616                     symbol, i2tv((int32_t) K_TRUNCATE));
   2617     add_applicative(K, ground_env, "round", kreal_to_integer, 2,
   2618                     symbol, i2tv((int32_t) K_ROUND_EVEN));
   2619     /* 12.8.5 rationalize, simplest-rational */
   2620     add_applicative(K, ground_env, "rationalize", krationalize, 0);
   2621     add_applicative(K, ground_env, "simplest-rational", ksimplest_rational, 0);
   2622     /* 12.9.1 real? */
   2623     add_applicative(K, ground_env, "real?", ftypep, 2, symbol, 
   2624                     p2tv(krealp));
   2625     /* 12.9.2 exp, log */
   2626     add_applicative(K, ground_env, "exp", kexp, 0);
   2627     add_applicative(K, ground_env, "log", klog, 0);
   2628     /* 12.9.3 sin, cos, tan */
   2629     add_applicative(K, ground_env, "sin", ktrig, 1, p2tv(sin));
   2630     add_applicative(K, ground_env, "cos", ktrig, 1, p2tv(cos));
   2631     add_applicative(K, ground_env, "tan", ktrig, 1, p2tv(tan));
   2632     /* 12.9.4 asin, acos, atan */
   2633     add_applicative(K, ground_env, "asin", katrig, 1, p2tv(asin));
   2634     add_applicative(K, ground_env, "acos", katrig, 1, p2tv(acos));
   2635     add_applicative(K, ground_env, "atan", katan, 0);
   2636     /* 12.9.5 sqrt */
   2637     add_applicative(K, ground_env, "sqrt", ksqrt, 0);
   2638     /* 12.9.6 expt */
   2639     add_applicative(K, ground_env, "expt", kexpt, 0);
   2640 
   2641     /* 12.? string->number, number->string */
   2642     add_applicative(K, ground_env, "string->number", string_to_number, 0);
   2643     add_applicative(K, ground_env, "number->string", number_to_string, 0);
   2644 }