klisp

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

imrat.h (5784B)


      1 /*
      2 ** imrat.h
      3 ** Arbitrary precision rational arithmetic routines.
      4 ** See Copyright Notice in klisp.h
      5 */
      6 
      7 /*
      8 ** SOURCE NOTE: This is mostly from the IMath library, written by
      9 ** M.J. Fromberger. It is adapted to klisp, mainly in the use of the
     10 ** klisp allocator and fixing of digit size to 32 bits.
     11 ** Imported from version (1.15) updated 01-Feb-2011 at 03:10 PM.
     12 */
     13 
     14 #ifndef IMRAT_H_
     15 #define IMRAT_H_
     16 
     17 #include "imath.h"
     18 
     19 /* Andres Navarro: klisp includes */
     20 #include "kobject.h"
     21 #include "kstate.h"
     22 
     23 #ifdef USE_C99
     24 #include <stdint.h>
     25 #endif
     26 
     27 #ifdef __cplusplus
     28 extern "C" {
     29 #endif
     30 
     31 /* Andres Navarro: Use kobject type instead */
     32     typedef Bigrat mpq_t, *mp_rat;
     33 
     34 #if 0
     35     typedef struct mpq {
     36         mpz_t   num;    /* Numerator            */
     37         mpz_t   den;    /* Denominator, <> 0 */
     38     } mpq_t, *mp_rat;
     39 #endif
     40 
     41 #define MP_NUMER_P(Q)  (&((Q)->num)) /* Pointer to numerator   */
     42 #define MP_DENOM_P(Q)  (&((Q)->den)) /* Pointer to denominator */
     43 
     44 /* Rounding constants */
     45 /* TODO: klisp add MP_ROUND_HALF_EVEN for compatibility with floating point */
     46     typedef enum { 
     47         MP_ROUND_DOWN, 
     48         MP_ROUND_HALF_UP, 
     49         MP_ROUND_UP, 
     50         MP_ROUND_HALF_DOWN 
     51     } mp_round_mode;
     52 
     53     mp_result mp_rat_init(klisp_State *K, mp_rat r);
     54     mp_rat    mp_rat_alloc(klisp_State *K);
     55     mp_result mp_rat_init_size(klisp_State *K, mp_rat r, mp_size n_prec, 
     56                                mp_size d_prec);
     57     mp_result mp_rat_init_copy(klisp_State *K, mp_rat r, mp_rat old);
     58     mp_result mp_rat_set_value(klisp_State *K, mp_rat r, int numer, int denom);
     59     void         mp_rat_clear(klisp_State *K, mp_rat r);
     60     void         mp_rat_free(klisp_State *K, mp_rat r);
     61     mp_result mp_rat_numer(klisp_State *K, mp_rat r, mp_int z);  /* z = num(r)  */
     62     mp_result mp_rat_denom(klisp_State *K, mp_rat r, mp_int z);  /* z = den(r)  */
     63 /* NOTE: this doesn't use the allocator */
     64     mp_sign   mp_rat_sign(mp_rat r);
     65 
     66     mp_result mp_rat_copy(klisp_State *K, mp_rat a, mp_rat c);  /* c = a          */
     67     void         mp_rat_zero(klisp_State *K, mp_rat r); /* r = 0          */
     68     mp_result mp_rat_abs(klisp_State *K, mp_rat a, mp_rat c); /* c = |a|        */
     69     mp_result mp_rat_neg(klisp_State *K, mp_rat a, mp_rat c); /* c = -a         */
     70     mp_result mp_rat_recip(klisp_State *K, mp_rat a, mp_rat c); /* c = 1 / a   */
     71 /* c = a + b   */
     72     mp_result mp_rat_add(klisp_State *K, mp_rat a, mp_rat b, mp_rat c);
     73 /* c = a - b   */
     74     mp_result mp_rat_sub(klisp_State *K, mp_rat a, mp_rat b, mp_rat c);
     75 /* c = a * b   */
     76     mp_result mp_rat_mul(klisp_State *K, mp_rat a, mp_rat b, mp_rat c);
     77 /* c = a / b   */
     78     mp_result mp_rat_div(klisp_State *K, mp_rat a, mp_rat b, mp_rat c);
     79 
     80 /* c = a + b   */
     81     mp_result mp_rat_add_int(klisp_State *K, mp_rat a, mp_int b, mp_rat c);
     82 /* c = a - b   */
     83     mp_result mp_rat_sub_int(klisp_State *K, mp_rat a, mp_int b, mp_rat c); 
     84 /* c = a * b   */
     85     mp_result mp_rat_mul_int(klisp_State *K, mp_rat a, mp_int b, mp_rat c); 
     86 /* c = a / b   */
     87     mp_result mp_rat_div_int(klisp_State *K, mp_rat a, mp_int b, mp_rat c); 
     88 /* c = a ^ b   */
     89     mp_result mp_rat_expt(klisp_State *K, mp_rat a, mp_small b, mp_rat c);  
     90 
     91 /* NOTE: because we may need to do multiplications, some of 
     92    these take a klisp_State */
     93     int          mp_rat_compare(klisp_State *K, mp_rat a, mp_rat b); /* a <=> b */
     94 /* |a| <=> |b| */
     95     int          mp_rat_compare_unsigned(klisp_State *K, mp_rat a, mp_rat b);  
     96 /* NOTE: this doesn't use the allocator */
     97     int          mp_rat_compare_zero(mp_rat r); /* r <=> 0        */
     98     int          mp_rat_compare_value(klisp_State *K, mp_rat r, mp_small n, 
     99                                       mp_small d); /* r <=> n/d */
    100 /* NOTE: this doesn't use the allocator */
    101     int          mp_rat_is_integer(mp_rat r);
    102 
    103 /* Convert to integers, if representable (returns MP_RANGE if not). */
    104 /* NOTE: this doesn't use the allocator */
    105     mp_result mp_rat_to_ints(mp_rat r, mp_small *num, mp_small *den);
    106 
    107 /* Convert to nul-terminated string with the specified radix, writing
    108    at most limit characters including the nul terminator. */
    109     mp_result mp_rat_to_string(klisp_State *K, mp_rat r, mp_size radix, char *str, 
    110                                int limit);
    111 
    112 /* Convert to decimal format in the specified radix and precision,
    113    writing at most limit characters including a nul terminator. */
    114     mp_result mp_rat_to_decimal(klisp_State *K, mp_rat r, mp_size radix, 
    115                                 mp_size prec, mp_round_mode round, 
    116                                 char *str, int limit);
    117 
    118 /* Return the number of characters required to represent r in the given
    119    radix.  May over-estimate. */
    120     mp_result mp_rat_string_len(mp_rat r, mp_size radix);
    121 
    122 /* Return the number of characters required to represent r in decimal
    123    format with the given radix and precision.  May over-estimate. */
    124     mp_result mp_rat_decimal_len(mp_rat r, mp_size radix, mp_size prec);
    125 
    126 /* Read zero-terminated string into r */
    127     mp_result mp_rat_read_string(klisp_State *K, mp_rat r, mp_size radix, 
    128                                  const char *str);
    129     mp_result mp_rat_read_cstring(klisp_State *K, mp_rat r, mp_size radix, 
    130                                   const char *str, char **end);
    131     mp_result mp_rat_read_ustring(klisp_State *K, mp_rat r, mp_size radix, 
    132                                   const char *str, char **end);
    133 
    134 /* Read zero-terminated string in decimal format into r */
    135     mp_result mp_rat_read_decimal(klisp_State *K, mp_rat r, mp_size radix, 
    136                                   const char *str);
    137     mp_result mp_rat_read_cdecimal(klisp_State *K, mp_rat r, mp_size radix, 
    138                                    const char *str, char **end);
    139 
    140 #ifdef __cplusplus
    141 }
    142 #endif
    143 #endif /* IMRAT_H_ */