Imported Upstream version 6.10.0.49

Former-commit-id: 1d6753294b2993e1fbf92de9366bb9544db4189b
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2020-01-16 16:38:04 +00:00
parent d94e79959b
commit 468663ddbb
48518 changed files with 2789335 additions and 61176 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,229 @@
/*
Name: gmp_compat.h
Purpose: Provide GMP compatiable routines for imath library
Author: David Peixotto
Copyright (c) 2012 Qualcomm Innovation Center, Inc. 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 IMATH_GMP_COMPAT_H_
#define IMATH_GMP_COMPAT_H_
#include "imath.h"
#include "imrat.h"
#include <stddef.h>
#define GMPZAPI(fun) impz_ ## fun
#define GMPQAPI(fun) impq_ ## fun
#ifdef __cplusplus
extern "C" {
#endif
/*************************************************************************
*
* Functions with direct translations
*
*************************************************************************/
/* gmp: mpq_clear */
void GMPQAPI(clear)(mp_rat x);
/* gmp: mpq_cmp */
int GMPQAPI(cmp)(mp_rat op1, mp_rat op2);
/* gmp: mpq_init */
void GMPQAPI(init)(mp_rat x);
/* gmp: mpq_mul */
void GMPQAPI(mul)(mp_rat product, mp_rat multiplier, mp_rat multiplicand);
/* gmp: mpq_set */
void GMPQAPI(set)(mp_rat rop, mp_rat op);
/* gmp: mpz_abs */
void GMPZAPI(abs)(mp_int rop, mp_int op);
/* gmp: mpz_add */
void GMPZAPI(add)(mp_int rop, mp_int op1, mp_int op2);
/* gmp: mpz_clear */
void GMPZAPI(clear)(mp_int x);
/* gmp: mpz_cmp_si */
int GMPZAPI(cmp_si)(mp_int op1, long op2);
/* gmp: mpz_cmpabs */
int GMPZAPI(cmpabs)(mp_int op1, mp_int op2);
/* gmp: mpz_cmp */
int GMPZAPI(cmp)(mp_int op1, mp_int op2);
/* gmp: mpz_init */
void GMPZAPI(init)(mp_int x);
/* gmp: mpz_mul */
void GMPZAPI(mul)(mp_int rop, mp_int op1, mp_int op2);
/* gmp: mpz_neg */
void GMPZAPI(neg)(mp_int rop, mp_int op);
/* gmp: mpz_set_si */
void GMPZAPI(set_si)(mp_int rop, long op);
/* gmp: mpz_set */
void GMPZAPI(set)(mp_int rop, mp_int op);
/* gmp: mpz_sub */
void GMPZAPI(sub)(mp_int rop, mp_int op1, mp_int op2);
/* gmp: mpz_swap */
void GMPZAPI(swap)(mp_int rop1, mp_int rop2);
/* gmp: mpq_sgn */
int GMPQAPI(sgn)(mp_rat op);
/* gmp: mpz_sgn */
int GMPZAPI(sgn)(mp_int op);
/* gmp: mpq_set_ui */
void GMPQAPI(set_ui)(mp_rat rop, unsigned long op1, unsigned long op2);
/* gmp: mpz_set_ui */
void GMPZAPI(set_ui)(mp_int rop, unsigned long op);
/* gmp: mpq_den_ref */
mp_int GMPQAPI(denref)(mp_rat op);
/* gmp: mpq_num_ref */
mp_int GMPQAPI(numref)(mp_rat op);
/* gmp: mpq_canonicalize */
void GMPQAPI(canonicalize)(mp_rat op);
/*************************************************************************
*
* Functions that can be implemented as a combination of imath functions
*
*************************************************************************/
/* gmp: mpz_addmul */
void GMPZAPI(addmul)(mp_int rop, mp_int op1, mp_int op2);
/* gmp: mpz_divexact */
void GMPZAPI(divexact)(mp_int q, mp_int n, mp_int d);
/* gmp: mpz_divisible_p */
int GMPZAPI(divisible_p)(mp_int n, mp_int d);
/* gmp: mpz_submul */
void GMPZAPI(submul)(mp_int rop, mp_int op1, mp_int op2);
/* gmp: mpz_add_ui */
void GMPZAPI(add_ui)(mp_int rop, mp_int op1, unsigned long op2);
/* gmp: mpz_divexact_ui */
void GMPZAPI(divexact_ui)(mp_int q, mp_int n, unsigned long d);
/* gmp: mpz_mul_ui */
void GMPZAPI(mul_ui)(mp_int rop, mp_int op1, unsigned long op2);
/* gmp: mpz_pow_ui */
void GMPZAPI(pow_ui)(mp_int rop, mp_int base, unsigned long exp);
/* gmp: mpz_sub_ui */
void GMPZAPI(sub_ui)(mp_int rop, mp_int op1, unsigned long op2);
/* gmp: mpz_fdiv_q_ui */
unsigned long GMPZAPI(fdiv_q_ui)(mp_int q, mp_int n, unsigned long d);
/* gmp: mpz_sizeinbase */
size_t GMPZAPI(sizeinbase)(mp_int op, int base);
/*************************************************************************
*
* Functions with different behavior in corner cases
*
*************************************************************************/
/* gmp: mpz_gcd */
/* gmp: When op1 = 0 and op2 = 0, return 0.*/
void GMPZAPI(gcd)(mp_int rop, mp_int op1, mp_int op2);
/* gmp: mpz_get_str */
/* gmp: If str is NULL then allocate space using the default allocator. */
char* GMPZAPI(get_str)(char *str, int radix, mp_int op);
/* gmp: mpq_get_str */
/* gmp: If str is NULL then allocate space using the default allocator. */
/* gmp: If value is a whole number do not print denomenator. */
/* TODO: Need to handle 0 values better. GMP prints 0/4 instead of 0.*/
char* GMPQAPI(get_str)(char *str, int radix, mp_rat op);
/* gmp: mpz_set_str */
/* gmp: Allow and ignore spaces in string. */
int GMPZAPI(set_str)(mp_int rop, char *str, int base);
/* gmp: mpq_set_str */
int GMPQAPI(set_str)(mp_rat rop, char *str, int base);
/* gmp: mpz_get_ui */
/* gmp: Return least significant bits if value is too big for a long. */
unsigned long GMPZAPI(get_ui)(mp_int op);
/* gmp: mpz_get_si */
/* gmp: Return least significant bits if value is too bit for a long. */
/* gmp: If value is too big for long, return the least significant
(8*sizeof(long)-1) bits from the op and set the sign bit according to
the sign of the op. */
long GMPZAPI(get_si)(mp_int op);
/* gmp: mpz_lcm */
/* gmp: When op1 = 0 or op2 = 0, return 0.*/
/* gmp: The resutl of lcm(a,b) is always positive. */
void GMPZAPI(lcm)(mp_int rop, mp_int op1, mp_int op2);
/* gmp: mpz_mul_2exp */
/* gmp: allow big values for op2 when op1 == 0 */
void GMPZAPI(mul_2exp)(mp_int rop, mp_int op1, unsigned long op2);
/*************************************************************************
*
* Functions needing expanded functionality
*
*************************************************************************/
/* gmp: mpz_cdiv_q */
void GMPZAPI(cdiv_q)(mp_int q, mp_int n, mp_int d);
/* gmp: mpz_fdiv_q */
void GMPZAPI(fdiv_q)(mp_int q, mp_int n, mp_int d);
/* gmp: mpz_fdiv_r */
void GMPZAPI(fdiv_r)(mp_int r, mp_int n, mp_int d);
/* gmp: mpz_tdiv_q */
void GMPZAPI(tdiv_q)(mp_int q, mp_int n, mp_int d);
/* gmp: mpz_export */
void* GMPZAPI(export)(void *rop, size_t *countp, int order, size_t size, int endian, size_t nails, mp_int op);
/* gmp: mpz_import */
void GMPZAPI(import)(mp_int rop, size_t count, int order, size_t size, int endian, size_t nails, const void* op);
#ifdef __cplusplus
}
#endif
#endif /* end IMATH_GMP_COMPAT_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,232 @@
/*
Name: imath.h
Purpose: Arbitrary precision integer 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 IMATH_H_
#define IMATH_H_
#include <stdint.h>
#include <limits.h>
#ifdef __cplusplus
extern "C" {
#endif
typedef unsigned char mp_sign;
typedef unsigned int mp_size;
typedef int mp_result;
typedef long mp_small; /* must be a signed type */
typedef unsigned long mp_usmall; /* must be an unsigned type */
/* Force building with uint64_t so that the library builds consistently
* whether we build from the makefile or by embedding imath in another project.
*/
#undef USE_64BIT_WORDS
#define USE_64BIT_WORDS
#ifdef USE_64BIT_WORDS
typedef uint32_t mp_digit;
typedef uint64_t mp_word;
#else
typedef uint16_t mp_digit;
typedef uint32_t mp_word;
#endif
typedef struct mpz {
mp_digit single;
mp_digit *digits;
mp_size alloc;
mp_size used;
mp_sign sign;
} mpz_t, *mp_int;
#define MP_DIGITS(Z) ((Z)->digits)
#define MP_ALLOC(Z) ((Z)->alloc)
#define MP_USED(Z) ((Z)->used)
#define MP_SIGN(Z) ((Z)->sign)
extern const mp_result MP_OK;
extern const mp_result MP_FALSE;
extern const mp_result MP_TRUE;
extern const mp_result MP_MEMORY;
extern const mp_result MP_RANGE;
extern const mp_result MP_UNDEF;
extern const mp_result MP_TRUNC;
extern const mp_result MP_BADARG;
extern const mp_result MP_MINERR;
#define MP_DIGIT_BIT (sizeof(mp_digit) * CHAR_BIT)
#define MP_WORD_BIT (sizeof(mp_word) * CHAR_BIT)
#define MP_SMALL_MIN LONG_MIN
#define MP_SMALL_MAX LONG_MAX
#define MP_USMALL_MIN ULONG_MIN
#define MP_USMALL_MAX ULONG_MAX
#ifdef USE_64BIT_WORDS
# define MP_DIGIT_MAX (UINT32_MAX * UINT64_C(1))
# define MP_WORD_MAX (UINT64_MAX)
#else
# define MP_DIGIT_MAX (UINT16_MAX * 1UL)
# define MP_WORD_MAX (UINT32_MAX * 1UL)
#endif
#define MP_MIN_RADIX 2
#define MP_MAX_RADIX 36
/* Values with fewer than this many significant digits use the standard
multiplication algorithm; otherwise, a recursive algorithm is used.
Choose a value to suit your platform.
*/
#define MP_MULT_THRESH 22
#define MP_DEFAULT_PREC 8 /* default memory allocation, in digits */
extern const mp_sign MP_NEG;
extern const mp_sign MP_ZPOS;
#define mp_int_is_odd(Z) ((Z)->digits[0] & 1)
#define mp_int_is_even(Z) !((Z)->digits[0] & 1)
mp_result mp_int_init(mp_int z);
mp_int mp_int_alloc(void);
mp_result mp_int_init_size(mp_int z, mp_size prec);
mp_result mp_int_init_copy(mp_int z, mp_int old);
mp_result mp_int_init_value(mp_int z, mp_small value);
mp_result mp_int_init_uvalue(mp_int z, mp_usmall uvalue);
mp_result mp_int_set_value(mp_int z, mp_small value);
mp_result mp_int_set_uvalue(mp_int z, mp_usmall uvalue);
void mp_int_clear(mp_int z);
void mp_int_free(mp_int z);
mp_result mp_int_copy(mp_int a, mp_int c); /* c = a */
void mp_int_swap(mp_int a, mp_int c); /* swap a, c */
void mp_int_zero(mp_int z); /* z = 0 */
mp_result mp_int_abs(mp_int a, mp_int c); /* c = |a| */
mp_result mp_int_neg(mp_int a, mp_int c); /* c = -a */
mp_result mp_int_add(mp_int a, mp_int b, mp_int c); /* c = a + b */
mp_result mp_int_add_value(mp_int a, mp_small value, mp_int c);
mp_result mp_int_sub(mp_int a, mp_int b, mp_int c); /* c = a - b */
mp_result mp_int_sub_value(mp_int a, mp_small value, mp_int c);
mp_result mp_int_mul(mp_int a, mp_int b, mp_int c); /* c = a * b */
mp_result mp_int_mul_value(mp_int a, mp_small value, mp_int c);
mp_result mp_int_mul_pow2(mp_int a, mp_small p2, mp_int c);
mp_result mp_int_sqr(mp_int a, mp_int c); /* c = a * a */
mp_result mp_int_div(mp_int a, mp_int b, /* q = a / b */
mp_int q, mp_int r); /* r = a % b */
mp_result mp_int_div_value(mp_int a, mp_small value, /* q = a / value */
mp_int q, mp_small *r); /* r = a % value */
mp_result mp_int_div_pow2(mp_int a, mp_small p2, /* q = a / 2^p2 */
mp_int q, mp_int r); /* r = q % 2^p2 */
mp_result mp_int_mod(mp_int a, mp_int m, mp_int c); /* c = a % m */
#define mp_int_mod_value(A, V, R) mp_int_div_value((A), (V), 0, (R))
mp_result mp_int_expt(mp_int a, mp_small b, mp_int c); /* c = a^b */
mp_result mp_int_expt_value(mp_small a, mp_small b, mp_int c); /* c = a^b */
mp_result mp_int_expt_full(mp_int a, mp_int b, mp_int c); /* c = a^b */
int mp_int_compare(mp_int a, mp_int b); /* a <=> b */
int mp_int_compare_unsigned(mp_int a, mp_int b); /* |a| <=> |b| */
int mp_int_compare_zero(mp_int z); /* a <=> 0 */
int mp_int_compare_value(mp_int z, mp_small v); /* a <=> v */
int mp_int_compare_uvalue(mp_int z, mp_usmall uv); /* a <=> uv */
/* Returns true if v|a, false otherwise (including errors) */
int mp_int_divisible_value(mp_int a, mp_small v);
/* Returns k >= 0 such that z = 2^k, if one exists; otherwise < 0 */
int mp_int_is_pow2(mp_int z);
mp_result mp_int_exptmod(mp_int a, mp_int b, mp_int m,
mp_int c); /* c = a^b (mod m) */
mp_result mp_int_exptmod_evalue(mp_int a, mp_small value,
mp_int m, mp_int c); /* c = a^v (mod m) */
mp_result mp_int_exptmod_bvalue(mp_small value, mp_int b,
mp_int m, mp_int c); /* c = v^b (mod m) */
mp_result mp_int_exptmod_known(mp_int a, mp_int b,
mp_int m, mp_int mu,
mp_int c); /* c = a^b (mod m) */
mp_result mp_int_redux_const(mp_int m, mp_int c);
mp_result mp_int_invmod(mp_int a, mp_int m, mp_int c); /* c = 1/a (mod m) */
mp_result mp_int_gcd(mp_int a, mp_int b, mp_int c); /* c = gcd(a, b) */
mp_result mp_int_egcd(mp_int a, mp_int b, mp_int c, /* c = gcd(a, b) */
mp_int x, mp_int y); /* c = ax + by */
mp_result mp_int_lcm(mp_int a, mp_int b, mp_int c); /* c = lcm(a, b) */
mp_result mp_int_root(mp_int a, mp_small b, mp_int c); /* c = floor(a^{1/b}) */
#define mp_int_sqrt(a, c) mp_int_root(a, 2, c) /* c = floor(sqrt(a)) */
/* Convert to a small int, if representable; else MP_RANGE */
mp_result mp_int_to_int(mp_int z, mp_small *out);
mp_result mp_int_to_uint(mp_int z, mp_usmall *out);
/* Convert to nul-terminated string with the specified radix, writing at
most limit characters including the nul terminator */
mp_result mp_int_to_string(mp_int z, mp_size radix,
char *str, int limit);
/* Return the number of characters required to represent
z in the given radix. May over-estimate. */
mp_result mp_int_string_len(mp_int z, mp_size radix);
/* Read zero-terminated string into z */
mp_result mp_int_read_string(mp_int z, mp_size radix, const char *str);
mp_result mp_int_read_cstring(mp_int z, mp_size radix, const char *str,
char **end);
/* Return the number of significant bits in z */
mp_result mp_int_count_bits(mp_int z);
/* Convert z to two's complement binary, writing at most limit bytes */
mp_result mp_int_to_binary(mp_int z, unsigned char *buf, int limit);
/* Read a two's complement binary value into z from the given buffer */
mp_result mp_int_read_binary(mp_int z, unsigned char *buf, int len);
/* Return the number of bytes required to represent z in binary. */
mp_result mp_int_binary_len(mp_int z);
/* Convert z to unsigned binary, writing at most limit bytes */
mp_result mp_int_to_unsigned(mp_int z, unsigned char *buf, int limit);
/* Read an unsigned binary value into z from the given buffer */
mp_result mp_int_read_unsigned(mp_int z, unsigned char *buf, int len);
/* Return the number of bytes required to represent z as unsigned output */
mp_result mp_int_unsigned_len(mp_int z);
/* Return a statically allocated string describing error code res */
const char *mp_error_string(mp_result res);
#if DEBUG
void s_print(char *tag, mp_int z);
void s_print_buf(char *tag, mp_digit *buf, mp_size num);
#endif
#ifdef __cplusplus
}
#endif
#endif /* end IMATH_H_ */

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,124 @@
/*
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_ */