Polly 19.0.0git
imath/imrat.h
Go to the documentation of this file.
1/*
2 Name: imrat.h
3 Purpose: Arbitrary precision rational arithmetic routines.
4 Author: M. J. Fromberger
5
6 Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved.
7
8 Permission is hereby granted, free of charge, to any person obtaining a copy
9 of this software and associated documentation files (the "Software"), to deal
10 in the Software without restriction, including without limitation the rights
11 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12 copies of the Software, and to permit persons to whom the Software is
13 furnished to do so, subject to the following conditions:
14
15 The above copyright notice and this permission notice shall be included in
16 all copies or substantial portions of the Software.
17
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
24 SOFTWARE.
25 */
26
27#ifndef IMRAT_H_
28#define IMRAT_H_
29
30#include <stdbool.h>
31
32#include "imath.h"
33
34#ifdef __cplusplus
35extern "C" {
36#endif
37
38typedef struct {
39 mpz_t num; /* Numerator */
40 mpz_t den; /* Denominator, <> 0 */
42
43/* Return a pointer to the numerator. */
44static inline mp_int MP_NUMER_P(mp_rat Q) { return &(Q->num); }
45
46/* Return a pointer to the denominator. */
47static inline mp_int MP_DENOM_P(mp_rat Q) { return &(Q->den); }
48
49/* Rounding constants */
50typedef enum {
56
57/** Initializes `r` with 1-digit precision and sets it to zero. This function
58 cannot fail unless `r` is NULL. */
60
61/** Allocates a fresh zero-valued `mpq_t` on the heap, returning NULL in case
62 of error. The only possible error is out-of-memory. */
64
65/** Reduces `r` in-place to lowest terms and canonical form.
66
67 Zero is represented as 0/1, one as 1/1, and signs are adjusted so that the
68 sign of the value is carried by the numerator. */
70
71/** Initializes `r` with at least `n_prec` digits of storage for the numerator
72 and `d_prec` digits of storage for the denominator, and value zero.
73
74 If either precision is zero, the default precision is used, rounded up to
75 the nearest word size. */
77
78/** Initializes `r` to be a copy of an already-initialized value in `old`. The
79 new copy does not share storage with the original. */
81
82/** Sets the value of `r` to the ratio of signed `numer` to signed `denom`. It
83 returns `MP_UNDEF` if `denom` is zero. */
85
86/** Sets the value of `r` to the ratio of unsigned `numer` to unsigned
87 `denom`. It returns `MP_UNDEF` if `denom` is zero. */
89
90/** Releases the storage used by `r`. */
91void mp_rat_clear(mp_rat r);
92
93/** Releases the storage used by `r` and also `r` itself.
94 This should only be used for `r` allocated by `mp_rat_alloc()`. */
95void mp_rat_free(mp_rat r);
96
97/** Sets `z` to a copy of the numerator of `r`. */
99
100/** Returns a pointer to the numerator of `r`. */
102
103/** Sets `z` to a copy of the denominator of `r`. */
105
106/** Returns a pointer to the denominator of `r`. */
108
109/** Reports the sign of `r`. */
111
112/** Sets `c` to a copy of the value of `a`. No new memory is allocated unless a
113 term of `a` has more significant digits than the corresponding term of `c`
114 has allocated. */
116
117/** Sets `r` to zero. The allocated storage of `r` is not changed. */
118void mp_rat_zero(mp_rat r);
119
120/** Sets `c` to the absolute value of `a`. */
122
123/** Sets `c` to the absolute value of `a`. */
125
126/** Sets `c` to the reciprocal of `a` if the reciprocal is defined.
127 It returns `MP_UNDEF` if `a` is zero. */
129
130/** Sets `c` to the sum of `a` and `b`. */
132
133/** Sets `c` to the difference of `a` less `b`. */
135
136/** Sets `c` to the product of `a` and `b`. */
138
139/** Sets `c` to the ratio `a / b` if that ratio is defined.
140 It returns `MP_UNDEF` if `b` is zero. */
142
143/** Sets `c` to the sum of `a` and integer `b`. */
145
146/** Sets `c` to the difference of `a` less integer `b`. */
148
149/** Sets `c` to the product of `a` and integer `b`. */
151
152/** Sets `c` to the ratio `a / b` if that ratio is defined.
153 It returns `MP_UNDEF` if `b` is zero. */
155
156/** Sets `c` to the value of `a` raised to the `b` power.
157 It returns `MP_RANGE` if `b < 0`. */
159
160/** Returns the comparator of `a` and `b`. */
162
163/** Returns the comparator of the magnitudes of `a` and `b`, disregarding their
164 signs. Neither `a` nor `b` is modified by the comparison. */
166
167/** Returns the comparator of `r` and zero. */
169
170/** Returns the comparator of `r` and the signed ratio `n / d`.
171 It returns `MP_UNDEF` if `d` is zero. */
173
174/** Reports whether `r` is an integer, having canonical denominator 1. */
176
177/** Reports whether the numerator and denominator of `r` can be represented as
178 small signed integers, and if so stores the corresponding values to `num`
179 and `den`. It returns `MP_RANGE` if either cannot be so represented. */
181
182/** Converts `r` to a zero-terminated string of the format `"n/d"` with `n` and
183 `d` in the specified radix and writing no more than `limit` bytes to the
184 given output buffer `str`. The output of the numerator includes a sign flag
185 if `r` is negative. Requires `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`. */
186mp_result mp_rat_to_string(mp_rat r, mp_size radix, char *str, int limit);
187
188/** Converts the value of `r` to a string in decimal-point notation with the
189 specified radix, writing no more than `limit` bytes of data to the given
190 output buffer. It generates `prec` digits of precision, and requires
191 `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`.
192
193 Ratios usually must be rounded when they are being converted for output as
194 a decimal value. There are four rounding modes currently supported:
195
196 MP_ROUND_DOWN
197 Truncates the value toward zero.
198 Example: 12.009 to 2dp becomes 12.00
199
200 MP_ROUND_UP
201 Rounds the value away from zero:
202 Example: 12.001 to 2dp becomes 12.01, but
203 12.000 to 2dp remains 12.00
204
205 MP_ROUND_HALF_DOWN
206 Rounds the value to nearest digit, half goes toward zero.
207 Example: 12.005 to 2dp becomes 12.00, but
208 12.006 to 2dp becomes 12.01
209
210 MP_ROUND_HALF_UP
211 Rounds the value to nearest digit, half rounds upward.
212 Example: 12.005 to 2dp becomes 12.01, but
213 12.004 to 2dp becomes 12.00
214*/
216 mp_round_mode round, char *str, int limit);
217
218/** Reports the minimum number of characters required to represent `r` as a
219 zero-terminated string in the given `radix`.
220 Requires `MP_MIN_RADIX <= radix <= MP_MAX_RADIX`. */
222
223/** Reports the length in bytes of the buffer needed to convert `r` using the
224 `mp_rat_to_decimal()` function with the specified `radix` and `prec`. The
225 buffer size estimate may slightly exceed the actual required capacity. */
227
228/** Sets `r` to the value represented by a zero-terminated string `str` in the
229 format `"n/d"` including a sign flag. It returns `MP_UNDEF` if the encoded
230 denominator has value zero. */
231mp_result mp_rat_read_string(mp_rat r, mp_size radix, const char *str);
232
233/** Sets `r` to the value represented by a zero-terminated string `str` in the
234 format `"n/d"` including a sign flag. It returns `MP_UNDEF` if the encoded
235 denominator has value zero. If `end` is not NULL then `*end` is set to
236 point to the first unconsumed character in the string, after parsing.
237*/
238mp_result mp_rat_read_cstring(mp_rat r, mp_size radix, const char *str,
239 char **end);
240
241/** Sets `r` to the value represented by a zero-terminated string `str` having
242 one of the following formats, each with an optional leading sign flag:
243
244 n : integer format, e.g. "123"
245 n/d : ratio format, e.g., "-12/5"
246 z.ffff : decimal format, e.g., "1.627"
247
248 It returns `MP_UNDEF` if the effective denominator is zero. If `end` is not
249 NULL then `*end` is set to point to the first unconsumed character in the
250 string, after parsing.
251*/
252mp_result mp_rat_read_ustring(mp_rat r, mp_size radix, const char *str,
253 char **end);
254
255/** Sets `r` to the value represented by a zero-terminated string `str` in the
256 format `"z.ffff"` including a sign flag. It returns `MP_UNDEF` if the
257 effective denominator. */
258mp_result mp_rat_read_decimal(mp_rat r, mp_size radix, const char *str);
259
260/** Sets `r` to the value represented by a zero-terminated string `str` in the
261 format `"z.ffff"` including a sign flag. It returns `MP_UNDEF` if the
262 effective denominator. If `end` is not NULL then `*end` is set to point to
263 the first unconsumed character in the string, after parsing. */
264mp_result mp_rat_read_cdecimal(mp_rat r, mp_size radix, const char *str,
265 char **end);
266
267#ifdef __cplusplus
268}
269#endif
270#endif /* IMRAT_H_ */
unsigned int mp_size
Definition: imath/imath.h:39
long mp_small
Definition: imath/imath.h:41
int mp_result
Definition: imath/imath.h:40
unsigned char mp_sign
Definition: imath/imath.h:38
unsigned long mp_usmall
Definition: imath/imath.h:42
static mp_int MP_DENOM_P(mp_rat Q)
Definition: imath/imrat.h:47
struct mpq_t * mp_rat
static mp_int MP_NUMER_P(mp_rat Q)
Definition: imath/imrat.h:44
mp_round_mode
Definition: imath/imrat.h:50
@ MP_ROUND_DOWN
Definition: imath/imrat.h:51
@ MP_ROUND_UP
Definition: imath/imrat.h:53
@ MP_ROUND_HALF_UP
Definition: imath/imrat.h:52
@ MP_ROUND_HALF_DOWN
Definition: imath/imrat.h:54
mp_rat mp_rat_alloc(void)
Allocates a fresh zero-valued mpq_t on the heap, returning NULL in case of error.
Definition: imath/imrat.c:64
const char * str
Definition: isl_test.c:2095
a(0)
b(9)
mpz_t den
Definition: imath/imrat.h:40
mpz_t num
Definition: imath/imrat.h:39
#define mp_rat_is_integer
Definition: wrap.h:147
#define mp_rat_init_size
Definition: wrap.h:146
#define mp_rat_string_len
Definition: wrap.h:163
#define mp_rat_div
Definition: wrap.h:140
#define mp_rat_compare_zero
Definition: wrap.h:135
#define mp_rat_read_string
Definition: wrap.h:156
#define mp_rat_add
Definition: wrap.h:128
#define mp_rat_compare
Definition: wrap.h:132
#define mp_rat_to_decimal
Definition: wrap.h:166
#define mp_rat_set_uvalue
Definition: wrap.h:160
#define mp_rat_read_cdecimal
Definition: wrap.h:153
#define mp_rat_expt
Definition: wrap.h:142
#define mp_rat_init_copy
Definition: wrap.h:145
#define mp_rat_mul_int
Definition: wrap.h:149
#define mp_rat_read_ustring
Definition: wrap.h:157
#define mp_rat_neg
Definition: wrap.h:150
#define mp_rat_denom
Definition: wrap.h:138
#define mp_rat_recip
Definition: wrap.h:158
#define mp_rat_mul
Definition: wrap.h:148
#define mp_rat_reduce
Definition: wrap.h:159
#define mp_rat_zero
Definition: wrap.h:169
#define mp_rat_numer_ref
Definition: wrap.h:152
#define mp_rat_sub_int
Definition: wrap.h:165
#define mp_rat_clear
Definition: wrap.h:131
#define mp_rat_copy
Definition: wrap.h:136
#define mp_rat_init
Definition: wrap.h:144
#define mp_rat_numer
Definition: wrap.h:151
#define mp_rat_to_ints
Definition: wrap.h:167
#define mp_rat_set_value
Definition: wrap.h:161
#define mp_rat_sub
Definition: wrap.h:164
#define mp_rat_denom_ref
Definition: wrap.h:139
#define mp_rat_free
Definition: wrap.h:143
#define mp_rat_div_int
Definition: wrap.h:141
#define mp_rat_read_decimal
Definition: wrap.h:155
#define mp_rat_to_string
Definition: wrap.h:168
#define mp_rat_compare_value
Definition: wrap.h:134
#define mp_rat_compare_unsigned
Definition: wrap.h:133
#define mp_rat_sign
Definition: wrap.h:162
#define mp_rat_read_cstring
Definition: wrap.h:154
#define mp_rat_add_int
Definition: wrap.h:129
#define mp_rat_abs
Definition: wrap.h:127
#define mp_rat_decimal_len
Definition: wrap.h:137
n
Definition: youcefn.c:8