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_ */