forked from OSchip/llvm-project
125 lines
5.3 KiB
C
125 lines
5.3 KiB
C
/*
|
|
Name: imrat.h
|
|
Purpose: Arbitrary precision rational arithmetic routines.
|
|
Author: M. J. Fromberger <http://spinning-yarns.org/michael/>
|
|
|
|
Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved.
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
in the Software without restriction, including without limitation the rights
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
all copies or substantial portions of the Software.
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
SOFTWARE.
|
|
*/
|
|
|
|
#ifndef IMRAT_H_
|
|
#define IMRAT_H_
|
|
|
|
#include "imath.h"
|
|
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
|
|
typedef struct mpq {
|
|
mpz_t num; /* Numerator */
|
|
mpz_t den; /* Denominator, <> 0 */
|
|
} mpq_t, *mp_rat;
|
|
|
|
#define MP_NUMER_P(Q) (&((Q)->num)) /* Pointer to numerator */
|
|
#define MP_DENOM_P(Q) (&((Q)->den)) /* Pointer to denominator */
|
|
|
|
/* Rounding constants */
|
|
typedef enum {
|
|
MP_ROUND_DOWN,
|
|
MP_ROUND_HALF_UP,
|
|
MP_ROUND_UP,
|
|
MP_ROUND_HALF_DOWN
|
|
} mp_round_mode;
|
|
|
|
mp_result mp_rat_init(mp_rat r);
|
|
mp_rat mp_rat_alloc(void);
|
|
mp_result mp_rat_reduce(mp_rat r);
|
|
mp_result mp_rat_init_size(mp_rat r, mp_size n_prec, mp_size d_prec);
|
|
mp_result mp_rat_init_copy(mp_rat r, mp_rat old);
|
|
mp_result mp_rat_set_value(mp_rat r, mp_small numer, mp_small denom);
|
|
mp_result mp_rat_set_uvalue(mp_rat r, mp_usmall numer, mp_usmall denom);
|
|
void mp_rat_clear(mp_rat r);
|
|
void mp_rat_free(mp_rat r);
|
|
mp_result mp_rat_numer(mp_rat r, mp_int z); /* z = num(r) */
|
|
mp_int mp_rat_numer_ref(mp_rat r); /* &num(r) */
|
|
mp_result mp_rat_denom(mp_rat r, mp_int z); /* z = den(r) */
|
|
mp_int mp_rat_denom_ref(mp_rat r); /* &den(r) */
|
|
mp_sign mp_rat_sign(mp_rat r);
|
|
|
|
mp_result mp_rat_copy(mp_rat a, mp_rat c); /* c = a */
|
|
void mp_rat_zero(mp_rat r); /* r = 0 */
|
|
mp_result mp_rat_abs(mp_rat a, mp_rat c); /* c = |a| */
|
|
mp_result mp_rat_neg(mp_rat a, mp_rat c); /* c = -a */
|
|
mp_result mp_rat_recip(mp_rat a, mp_rat c); /* c = 1 / a */
|
|
mp_result mp_rat_add(mp_rat a, mp_rat b, mp_rat c); /* c = a + b */
|
|
mp_result mp_rat_sub(mp_rat a, mp_rat b, mp_rat c); /* c = a - b */
|
|
mp_result mp_rat_mul(mp_rat a, mp_rat b, mp_rat c); /* c = a * b */
|
|
mp_result mp_rat_div(mp_rat a, mp_rat b, mp_rat c); /* c = a / b */
|
|
|
|
mp_result mp_rat_add_int(mp_rat a, mp_int b, mp_rat c); /* c = a + b */
|
|
mp_result mp_rat_sub_int(mp_rat a, mp_int b, mp_rat c); /* c = a - b */
|
|
mp_result mp_rat_mul_int(mp_rat a, mp_int b, mp_rat c); /* c = a * b */
|
|
mp_result mp_rat_div_int(mp_rat a, mp_int b, mp_rat c); /* c = a / b */
|
|
mp_result mp_rat_expt(mp_rat a, mp_small b, mp_rat c); /* c = a ^ b */
|
|
|
|
int mp_rat_compare(mp_rat a, mp_rat b); /* a <=> b */
|
|
int mp_rat_compare_unsigned(mp_rat a, mp_rat b); /* |a| <=> |b| */
|
|
int mp_rat_compare_zero(mp_rat r); /* r <=> 0 */
|
|
int mp_rat_compare_value(mp_rat r, mp_small n, mp_small d); /* r <=> n/d */
|
|
int mp_rat_is_integer(mp_rat r);
|
|
|
|
/* Convert to integers, if representable (returns MP_RANGE if not). */
|
|
mp_result mp_rat_to_ints(mp_rat r, mp_small *num, mp_small *den);
|
|
|
|
/* Convert to nul-terminated string with the specified radix, writing
|
|
at most limit characters including the nul terminator. */
|
|
mp_result mp_rat_to_string(mp_rat r, mp_size radix, char *str, int limit);
|
|
|
|
/* Convert to decimal format in the specified radix and precision,
|
|
writing at most limit characters including a nul terminator. */
|
|
mp_result mp_rat_to_decimal(mp_rat r, mp_size radix, mp_size prec,
|
|
mp_round_mode round, char *str, int limit);
|
|
|
|
/* Return the number of characters required to represent r in the given
|
|
radix. May over-estimate. */
|
|
mp_result mp_rat_string_len(mp_rat r, mp_size radix);
|
|
|
|
/* Return the number of characters required to represent r in decimal
|
|
format with the given radix and precision. May over-estimate. */
|
|
mp_result mp_rat_decimal_len(mp_rat r, mp_size radix, mp_size prec);
|
|
|
|
/* Read zero-terminated string into r */
|
|
mp_result mp_rat_read_string(mp_rat r, mp_size radix, const char *str);
|
|
mp_result mp_rat_read_cstring(mp_rat r, mp_size radix, const char *str,
|
|
char **end);
|
|
mp_result mp_rat_read_ustring(mp_rat r, mp_size radix, const char *str,
|
|
char **end);
|
|
|
|
/* Read zero-terminated string in decimal format into r */
|
|
mp_result mp_rat_read_decimal(mp_rat r, mp_size radix, const char *str);
|
|
mp_result mp_rat_read_cdecimal(mp_rat r, mp_size radix, const char *str,
|
|
char **end);
|
|
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
#endif /* IMRAT_H_ */
|