3 Purpose: Arbitrary precision rational arithmetic routines.
4 Author: M. J. Fromberger
6 Copyright (C) 2002-2007 Michael J. Fromberger, All Rights Reserved.
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:
15 The above copyright notice and this permission notice shall be included in
16 all copies or substantial portions of the Software.
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
33 #define MP_NUMER_SIGN(Q) (MP_NUMER_P(Q)->sign)
34 #define MP_DENOM_SIGN(Q) (MP_DENOM_P(Q)->sign)
36 #define TEMP(K) (temp + (K))
39 if ((res = (E)) != MP_OK) goto CLEANUP; \
43 /* Reduce the given rational, in place, to lowest terms and canonical form.
44 Zero is represented as 0/1, one as 1/1. Signs are adjusted so that the sign
45 of the numerator is definitive. */
46 static mp_result
s_rat_reduce(mp_rat r
);
48 /* Common code for addition and subtraction operations on rationals. */
49 static mp_result
s_rat_combine(mp_rat a
, mp_rat b
, mp_rat c
,
50 mp_result (*comb_f
)(mp_int
, mp_int
, mp_int
));
52 mp_result
mp_rat_init(mp_rat r
) {
55 if ((res
= mp_int_init(MP_NUMER_P(r
))) != MP_OK
) return res
;
56 if ((res
= mp_int_init(MP_DENOM_P(r
))) != MP_OK
) {
57 mp_int_clear(MP_NUMER_P(r
));
61 return mp_int_set_value(MP_DENOM_P(r
), 1);
64 mp_rat
mp_rat_alloc(void) {
65 mp_rat out
= malloc(sizeof(*out
));
68 if (mp_rat_init(out
) != MP_OK
) {
77 mp_result
mp_rat_reduce(mp_rat r
) { return s_rat_reduce(r
); }
79 mp_result
mp_rat_init_size(mp_rat r
, mp_size n_prec
, mp_size d_prec
) {
82 if ((res
= mp_int_init_size(MP_NUMER_P(r
), n_prec
)) != MP_OK
) {
85 if ((res
= mp_int_init_size(MP_DENOM_P(r
), d_prec
)) != MP_OK
) {
86 mp_int_clear(MP_NUMER_P(r
));
90 return mp_int_set_value(MP_DENOM_P(r
), 1);
93 mp_result
mp_rat_init_copy(mp_rat r
, mp_rat old
) {
96 if ((res
= mp_int_init_copy(MP_NUMER_P(r
), MP_NUMER_P(old
))) != MP_OK
) {
99 if ((res
= mp_int_init_copy(MP_DENOM_P(r
), MP_DENOM_P(old
))) != MP_OK
)
100 mp_int_clear(MP_NUMER_P(r
));
105 mp_result
mp_rat_set_value(mp_rat r
, mp_small numer
, mp_small denom
) {
108 if (denom
== 0) return MP_UNDEF
;
110 if ((res
= mp_int_set_value(MP_NUMER_P(r
), numer
)) != MP_OK
) {
113 if ((res
= mp_int_set_value(MP_DENOM_P(r
), denom
)) != MP_OK
) {
117 return s_rat_reduce(r
);
120 mp_result
mp_rat_set_uvalue(mp_rat r
, mp_usmall numer
, mp_usmall denom
) {
123 if (denom
== 0) return MP_UNDEF
;
125 if ((res
= mp_int_set_uvalue(MP_NUMER_P(r
), numer
)) != MP_OK
) {
128 if ((res
= mp_int_set_uvalue(MP_DENOM_P(r
), denom
)) != MP_OK
) {
132 return s_rat_reduce(r
);
135 void mp_rat_clear(mp_rat r
) {
136 mp_int_clear(MP_NUMER_P(r
));
137 mp_int_clear(MP_DENOM_P(r
));
140 void mp_rat_free(mp_rat r
) {
143 if (r
->num
.digits
!= NULL
) mp_rat_clear(r
);
148 mp_result
mp_rat_numer(mp_rat r
, mp_int z
) {
149 return mp_int_copy(MP_NUMER_P(r
), z
);
152 mp_int
mp_rat_numer_ref(mp_rat r
) { return MP_NUMER_P(r
); }
154 mp_result
mp_rat_denom(mp_rat r
, mp_int z
) {
155 return mp_int_copy(MP_DENOM_P(r
), z
);
158 mp_int
mp_rat_denom_ref(mp_rat r
) { return MP_DENOM_P(r
); }
160 mp_sign
mp_rat_sign(mp_rat r
) { return MP_NUMER_SIGN(r
); }
162 mp_result
mp_rat_copy(mp_rat a
, mp_rat c
) {
165 if ((res
= mp_int_copy(MP_NUMER_P(a
), MP_NUMER_P(c
))) != MP_OK
) {
169 res
= mp_int_copy(MP_DENOM_P(a
), MP_DENOM_P(c
));
173 void mp_rat_zero(mp_rat r
) {
174 mp_int_zero(MP_NUMER_P(r
));
175 mp_int_set_value(MP_DENOM_P(r
), 1);
178 mp_result
mp_rat_abs(mp_rat a
, mp_rat c
) {
181 if ((res
= mp_int_abs(MP_NUMER_P(a
), MP_NUMER_P(c
))) != MP_OK
) {
185 res
= mp_int_abs(MP_DENOM_P(a
), MP_DENOM_P(c
));
189 mp_result
mp_rat_neg(mp_rat a
, mp_rat c
) {
192 if ((res
= mp_int_neg(MP_NUMER_P(a
), MP_NUMER_P(c
))) != MP_OK
) {
196 res
= mp_int_copy(MP_DENOM_P(a
), MP_DENOM_P(c
));
200 mp_result
mp_rat_recip(mp_rat a
, mp_rat c
) {
203 if (mp_rat_compare_zero(a
) == 0) return MP_UNDEF
;
205 if ((res
= mp_rat_copy(a
, c
)) != MP_OK
) return res
;
207 mp_int_swap(MP_NUMER_P(c
), MP_DENOM_P(c
));
209 /* Restore the signs of the swapped elements */
211 mp_sign tmp
= MP_NUMER_SIGN(c
);
213 MP_NUMER_SIGN(c
) = MP_DENOM_SIGN(c
);
214 MP_DENOM_SIGN(c
) = tmp
;
220 mp_result
mp_rat_add(mp_rat a
, mp_rat b
, mp_rat c
) {
221 return s_rat_combine(a
, b
, c
, mp_int_add
);
224 mp_result
mp_rat_sub(mp_rat a
, mp_rat b
, mp_rat c
) {
225 return s_rat_combine(a
, b
, c
, mp_int_sub
);
228 mp_result
mp_rat_mul(mp_rat a
, mp_rat b
, mp_rat c
) {
231 if ((res
= mp_int_mul(MP_NUMER_P(a
), MP_NUMER_P(b
), MP_NUMER_P(c
))) != MP_OK
)
234 if (mp_int_compare_zero(MP_NUMER_P(c
)) != 0) {
235 res
= mp_int_mul(MP_DENOM_P(a
), MP_DENOM_P(b
), MP_DENOM_P(c
));
241 return s_rat_reduce(c
);
244 mp_result
mp_rat_div(mp_rat a
, mp_rat b
, mp_rat c
) {
245 mp_result res
= MP_OK
;
247 if (mp_rat_compare_zero(b
) == 0) return MP_UNDEF
;
249 if (c
== a
|| c
== b
) {
252 if ((res
= mp_int_init(&tmp
)) != MP_OK
) return res
;
253 if ((res
= mp_int_mul(MP_NUMER_P(a
), MP_DENOM_P(b
), &tmp
)) != MP_OK
) {
256 if ((res
= mp_int_mul(MP_DENOM_P(a
), MP_NUMER_P(b
), MP_DENOM_P(c
))) !=
260 res
= mp_int_copy(&tmp
, MP_NUMER_P(c
));
265 if ((res
= mp_int_mul(MP_NUMER_P(a
), MP_DENOM_P(b
), MP_NUMER_P(c
))) !=
269 if ((res
= mp_int_mul(MP_DENOM_P(a
), MP_NUMER_P(b
), MP_DENOM_P(c
))) !=
278 return s_rat_reduce(c
);
282 mp_result
mp_rat_add_int(mp_rat a
, mp_int b
, mp_rat c
) {
286 if ((res
= mp_int_init_copy(&tmp
, b
)) != MP_OK
) {
289 if ((res
= mp_int_mul(&tmp
, MP_DENOM_P(a
), &tmp
)) != MP_OK
) {
292 if ((res
= mp_rat_copy(a
, c
)) != MP_OK
) {
295 if ((res
= mp_int_add(MP_NUMER_P(c
), &tmp
, MP_NUMER_P(c
))) != MP_OK
) {
299 res
= s_rat_reduce(c
);
306 mp_result
mp_rat_sub_int(mp_rat a
, mp_int b
, mp_rat c
) {
310 if ((res
= mp_int_init_copy(&tmp
, b
)) != MP_OK
) {
313 if ((res
= mp_int_mul(&tmp
, MP_DENOM_P(a
), &tmp
)) != MP_OK
) {
316 if ((res
= mp_rat_copy(a
, c
)) != MP_OK
) {
319 if ((res
= mp_int_sub(MP_NUMER_P(c
), &tmp
, MP_NUMER_P(c
))) != MP_OK
) {
323 res
= s_rat_reduce(c
);
330 mp_result
mp_rat_mul_int(mp_rat a
, mp_int b
, mp_rat c
) {
333 if ((res
= mp_rat_copy(a
, c
)) != MP_OK
) {
336 if ((res
= mp_int_mul(MP_NUMER_P(c
), b
, MP_NUMER_P(c
))) != MP_OK
) {
340 return s_rat_reduce(c
);
343 mp_result
mp_rat_div_int(mp_rat a
, mp_int b
, mp_rat c
) {
346 if (mp_int_compare_zero(b
) == 0) {
349 if ((res
= mp_rat_copy(a
, c
)) != MP_OK
) {
352 if ((res
= mp_int_mul(MP_DENOM_P(c
), b
, MP_DENOM_P(c
))) != MP_OK
) {
356 return s_rat_reduce(c
);
359 mp_result
mp_rat_expt(mp_rat a
, mp_small b
, mp_rat c
) {
362 /* Special cases for easy powers. */
364 return mp_rat_set_value(c
, 1, 1);
366 return mp_rat_copy(a
, c
);
369 /* Since rationals are always stored in lowest terms, it is not necessary to
370 reduce again when raising to an integer power. */
371 if ((res
= mp_int_expt(MP_NUMER_P(a
), b
, MP_NUMER_P(c
))) != MP_OK
) {
375 return mp_int_expt(MP_DENOM_P(a
), b
, MP_DENOM_P(c
));
378 int mp_rat_compare(mp_rat a
, mp_rat b
) {
379 /* Quick check for opposite signs. Works because the sign of the numerator
380 is always definitive. */
381 if (MP_NUMER_SIGN(a
) != MP_NUMER_SIGN(b
)) {
382 if (MP_NUMER_SIGN(a
) == MP_ZPOS
) {
388 /* Compare absolute magnitudes; if both are positive, the answer stands,
389 otherwise it needs to be reflected about zero. */
390 int cmp
= mp_rat_compare_unsigned(a
, b
);
392 if (MP_NUMER_SIGN(a
) == MP_ZPOS
) {
400 int mp_rat_compare_unsigned(mp_rat a
, mp_rat b
) {
401 /* If the denominators are equal, we can quickly compare numerators without
402 multiplying. Otherwise, we actually have to do some work. */
403 if (mp_int_compare_unsigned(MP_DENOM_P(a
), MP_DENOM_P(b
)) == 0) {
404 return mp_int_compare_unsigned(MP_NUMER_P(a
), MP_NUMER_P(b
));
410 int cmp
= INT_MAX
, last
= 0;
412 /* t0 = num(a) * den(b), t1 = num(b) * den(a) */
413 SETUP(mp_int_init_copy(TEMP(last
), MP_NUMER_P(a
)), last
);
414 SETUP(mp_int_init_copy(TEMP(last
), MP_NUMER_P(b
)), last
);
416 if ((res
= mp_int_mul(TEMP(0), MP_DENOM_P(b
), TEMP(0))) != MP_OK
||
417 (res
= mp_int_mul(TEMP(1), MP_DENOM_P(a
), TEMP(1))) != MP_OK
) {
421 cmp
= mp_int_compare_unsigned(TEMP(0), TEMP(1));
424 while (--last
>= 0) {
425 mp_int_clear(TEMP(last
));
432 int mp_rat_compare_zero(mp_rat r
) { return mp_int_compare_zero(MP_NUMER_P(r
)); }
434 int mp_rat_compare_value(mp_rat r
, mp_small n
, mp_small d
) {
439 if ((res
= mp_rat_init(&tmp
)) != MP_OK
) {
442 if ((res
= mp_rat_set_value(&tmp
, n
, d
)) != MP_OK
) {
446 out
= mp_rat_compare(r
, &tmp
);
453 bool mp_rat_is_integer(mp_rat r
) {
454 return (mp_int_compare_value(MP_DENOM_P(r
), 1) == 0);
457 mp_result
mp_rat_to_ints(mp_rat r
, mp_small
*num
, mp_small
*den
) {
460 if ((res
= mp_int_to_int(MP_NUMER_P(r
), num
)) != MP_OK
) {
464 res
= mp_int_to_int(MP_DENOM_P(r
), den
);
468 mp_result
mp_rat_to_string(mp_rat r
, mp_size radix
, char *str
, int limit
) {
469 /* Write the numerator. The sign of the rational number is written by the
470 underlying integer implementation. */
472 if ((res
= mp_int_to_string(MP_NUMER_P(r
), radix
, str
, limit
)) != MP_OK
) {
476 /* If the value is zero, don't bother writing any denominator */
477 if (mp_int_compare_zero(MP_NUMER_P(r
)) == 0) {
481 /* Locate the end of the numerator, and make sure we are not going to exceed
482 the limit by writing a slash. */
483 int len
= strlen(str
);
484 char *start
= str
+ len
;
486 if (limit
== 0) return MP_TRUNC
;
491 return mp_int_to_string(MP_DENOM_P(r
), radix
, start
, limit
);
494 mp_result
mp_rat_to_decimal(mp_rat r
, mp_size radix
, mp_size prec
,
495 mp_round_mode round
, char *str
, int limit
) {
500 SETUP(mp_int_init_copy(TEMP(last
), MP_NUMER_P(r
)), last
);
501 SETUP(mp_int_init(TEMP(last
)), last
);
502 SETUP(mp_int_init(TEMP(last
)), last
);
504 /* Get the unsigned integer part by dividing denominator into the absolute
505 value of the numerator. */
506 mp_int_abs(TEMP(0), TEMP(0));
507 if ((res
= mp_int_div(TEMP(0), MP_DENOM_P(r
), TEMP(0), TEMP(1))) != MP_OK
) {
511 /* Now: T0 = integer portion, unsigned;
512 T1 = remainder, from which fractional part is computed. */
514 /* Count up leading zeroes after the radix point. */
515 int zprec
= (int)prec
;
517 for (lead_0
= 0; lead_0
< zprec
&& mp_int_compare(TEMP(1), MP_DENOM_P(r
)) < 0;
519 if ((res
= mp_int_mul_value(TEMP(1), radix
, TEMP(1))) != MP_OK
) {
524 /* Multiply remainder by a power of the radix sufficient to get the right
525 number of significant figures. */
526 if (zprec
> lead_0
) {
527 if ((res
= mp_int_expt_value(radix
, zprec
- lead_0
, TEMP(2))) != MP_OK
) {
530 if ((res
= mp_int_mul(TEMP(1), TEMP(2), TEMP(1))) != MP_OK
) {
534 if ((res
= mp_int_div(TEMP(1), MP_DENOM_P(r
), TEMP(1), TEMP(2))) != MP_OK
) {
538 /* Now: T1 = significant digits of fractional part;
539 T2 = leftovers, to use for rounding.
541 At this point, what we do depends on the rounding mode. The default is
542 MP_ROUND_DOWN, for which everything is as it should be already.
548 if (mp_int_compare_zero(TEMP(2)) != 0) {
550 res
= mp_int_add_value(TEMP(0), 1, TEMP(0));
552 res
= mp_int_add_value(TEMP(1), 1, TEMP(1));
557 case MP_ROUND_HALF_UP
:
558 case MP_ROUND_HALF_DOWN
:
559 if ((res
= mp_int_mul_pow2(TEMP(2), 1, TEMP(2))) != MP_OK
) {
563 cmp
= mp_int_compare(TEMP(2), MP_DENOM_P(r
));
565 if (round
== MP_ROUND_HALF_UP
) cmp
+= 1;
569 res
= mp_int_add_value(TEMP(0), 1, TEMP(0));
571 res
= mp_int_add_value(TEMP(1), 1, TEMP(1));
577 break; /* No action required */
580 return MP_BADARG
; /* Invalid rounding specifier */
586 /* The sign of the output should be the sign of the numerator, but if all the
587 displayed digits will be zero due to the precision, a negative shouldn't
591 if (MP_NUMER_SIGN(r
) == MP_NEG
&& (mp_int_compare_zero(TEMP(0)) != 0 ||
592 mp_int_compare_zero(TEMP(1)) != 0)) {
597 if ((res
= mp_int_to_string(TEMP(0), radix
, start
, left
)) != MP_OK
) {
601 int len
= strlen(start
);
605 if (prec
== 0) goto CLEANUP
;
610 if (left
< zprec
+ 1) {
615 memset(start
, '0', lead_0
- 1);
619 res
= mp_int_to_string(TEMP(1), radix
, start
, left
);
622 while (--last
>= 0) mp_int_clear(TEMP(last
));
627 mp_result
mp_rat_string_len(mp_rat r
, mp_size radix
) {
629 mp_result n_len
= mp_int_string_len(MP_NUMER_P(r
), radix
);
631 if (mp_int_compare_zero(MP_NUMER_P(r
)) != 0) {
632 d_len
= mp_int_string_len(MP_DENOM_P(r
), radix
);
635 /* Though simplistic, this formula is correct. Space for the sign flag is
636 included in n_len, and the space for the NUL that is counted in n_len
637 counts for the separator here. The space for the NUL counted in d_len
638 counts for the final terminator here. */
640 return n_len
+ d_len
;
643 mp_result
mp_rat_decimal_len(mp_rat r
, mp_size radix
, mp_size prec
) {
645 int z_len
= mp_int_string_len(MP_NUMER_P(r
), radix
);
648 f_len
= 1; /* terminator only */
650 f_len
= 1 + prec
+ 1; /* decimal point, digits, terminator */
653 return z_len
+ f_len
;
656 mp_result
mp_rat_read_string(mp_rat r
, mp_size radix
, const char *str
) {
657 return mp_rat_read_cstring(r
, radix
, str
, NULL
);
660 mp_result
mp_rat_read_cstring(mp_rat r
, mp_size radix
, const char *str
,
665 if ((res
= mp_int_read_cstring(MP_NUMER_P(r
), radix
, str
, &endp
)) != MP_OK
&&
670 /* Skip whitespace between numerator and (possible) separator */
671 while (isspace((unsigned char)*endp
)) {
675 /* If there is no separator, we will stop reading at this point. */
677 mp_int_set_value(MP_DENOM_P(r
), 1);
678 if (end
!= NULL
) *end
= endp
;
682 ++endp
; /* skip separator */
683 if ((res
= mp_int_read_cstring(MP_DENOM_P(r
), radix
, endp
, end
)) != MP_OK
) {
687 /* Make sure the value is well-defined */
688 if (mp_int_compare_zero(MP_DENOM_P(r
)) == 0) {
692 /* Reduce to lowest terms */
693 return s_rat_reduce(r
);
696 /* Read a string and figure out what format it's in. The radix may be supplied
697 as zero to use "default" behaviour.
699 This function will accept either a/b notation or decimal notation.
701 mp_result
mp_rat_read_ustring(mp_rat r
, mp_size radix
, const char *str
,
706 if (radix
== 0) radix
= 10; /* default to decimal input */
708 res
= mp_rat_read_cstring(r
, radix
, str
, &endp
);
709 if (res
== MP_TRUNC
&& *endp
== '.') {
710 res
= mp_rat_read_cdecimal(r
, radix
, str
, &endp
);
712 if (end
!= NULL
) *end
= endp
;
716 mp_result
mp_rat_read_decimal(mp_rat r
, mp_size radix
, const char *str
) {
717 return mp_rat_read_cdecimal(r
, radix
, str
, NULL
);
720 mp_result
mp_rat_read_cdecimal(mp_rat r
, mp_size radix
, const char *str
,
726 while (isspace((unsigned char)*str
)) ++str
;
736 if ((res
= mp_int_read_cstring(MP_NUMER_P(r
), radix
, str
, &endp
)) != MP_OK
&&
741 /* This needs to be here. */
742 (void)mp_int_set_value(MP_DENOM_P(r
), 1);
745 if (end
!= NULL
) *end
= endp
;
749 /* If the character following the decimal point is whitespace or a sign flag,
750 we will consider this a truncated value. This special case is because
751 mp_int_read_string() will consider whitespace or sign flags to be valid
752 starting characters for a value, and we do not want them following the
755 Once we have done this check, it is safe to read in the value of the
756 fractional piece as a regular old integer.
760 if (end
!= NULL
) *end
= endp
;
762 } else if (isspace((unsigned char)*endp
) || *endp
== '-' || *endp
== '+') {
770 /* Make a temporary to hold the part after the decimal point. */
771 if ((res
= mp_int_init(&frac
)) != MP_OK
) {
775 if ((res
= mp_int_read_cstring(&frac
, radix
, endp
, &endp
)) != MP_OK
&&
780 /* Save this response for later. */
783 if (mp_int_compare_zero(&frac
) == 0) goto FINISHED
;
785 /* Discard trailing zeroes (somewhat inefficiently) */
786 while (mp_int_divisible_value(&frac
, radix
)) {
787 if ((res
= mp_int_div_value(&frac
, radix
, &frac
, NULL
)) != MP_OK
) {
792 /* Count leading zeros after the decimal point */
793 while (save
[num_lz
] == '0') {
797 /* Find the least power of the radix that is at least as large as the
798 significant value of the fractional part, ignoring leading zeroes. */
799 (void)mp_int_set_value(MP_DENOM_P(r
), radix
);
801 while (mp_int_compare(MP_DENOM_P(r
), &frac
) < 0) {
802 if ((res
= mp_int_mul_value(MP_DENOM_P(r
), radix
, MP_DENOM_P(r
))) !=
808 /* Also shift by enough to account for leading zeroes */
810 if ((res
= mp_int_mul_value(MP_DENOM_P(r
), radix
, MP_DENOM_P(r
))) !=
818 /* Having found this power, shift the numerator leftward that many, digits,
819 and add the nonzero significant digits of the fractional part to get the
821 if ((res
= mp_int_mul(MP_NUMER_P(r
), MP_DENOM_P(r
), MP_NUMER_P(r
))) !=
826 { /* This addition needs to be unsigned. */
827 MP_NUMER_SIGN(r
) = MP_ZPOS
;
828 if ((res
= mp_int_add(MP_NUMER_P(r
), &frac
, MP_NUMER_P(r
))) != MP_OK
) {
832 MP_NUMER_SIGN(r
) = osign
;
834 if ((res
= s_rat_reduce(r
)) != MP_OK
) goto CLEANUP
;
836 /* At this point, what we return depends on whether reading the fractional
837 part was truncated or not. That information is saved from when we
838 called mp_int_read_string() above. */
841 if (end
!= NULL
) *end
= endp
;
850 /* Private functions for internal use. Make unchecked assumptions about format
851 and validity of inputs. */
853 static mp_result
s_rat_reduce(mp_rat r
) {
855 mp_result res
= MP_OK
;
857 if (mp_int_compare_zero(MP_NUMER_P(r
)) == 0) {
858 mp_int_set_value(MP_DENOM_P(r
), 1);
862 /* If the greatest common divisor of the numerator and denominator is greater
863 than 1, divide it out. */
864 if ((res
= mp_int_init(&gcd
)) != MP_OK
) return res
;
866 if ((res
= mp_int_gcd(MP_NUMER_P(r
), MP_DENOM_P(r
), &gcd
)) != MP_OK
) {
870 if (mp_int_compare_value(&gcd
, 1) != 0) {
871 if ((res
= mp_int_div(MP_NUMER_P(r
), &gcd
, MP_NUMER_P(r
), NULL
)) != MP_OK
) {
874 if ((res
= mp_int_div(MP_DENOM_P(r
), &gcd
, MP_DENOM_P(r
), NULL
)) != MP_OK
) {
879 /* Fix up the signs of numerator and denominator */
880 if (MP_NUMER_SIGN(r
) == MP_DENOM_SIGN(r
)) {
881 MP_NUMER_SIGN(r
) = MP_DENOM_SIGN(r
) = MP_ZPOS
;
883 MP_NUMER_SIGN(r
) = MP_NEG
;
884 MP_DENOM_SIGN(r
) = MP_ZPOS
;
893 static mp_result
s_rat_combine(mp_rat a
, mp_rat b
, mp_rat c
,
894 mp_result (*comb_f
)(mp_int
, mp_int
, mp_int
)) {
897 /* Shortcut when denominators are already common */
898 if (mp_int_compare(MP_DENOM_P(a
), MP_DENOM_P(b
)) == 0) {
899 if ((res
= (comb_f
)(MP_NUMER_P(a
), MP_NUMER_P(b
), MP_NUMER_P(c
))) !=
903 if ((res
= mp_int_copy(MP_DENOM_P(a
), MP_DENOM_P(c
))) != MP_OK
) {
907 return s_rat_reduce(c
);
912 SETUP(mp_int_init_copy(TEMP(last
), MP_NUMER_P(a
)), last
);
913 SETUP(mp_int_init_copy(TEMP(last
), MP_NUMER_P(b
)), last
);
915 if ((res
= mp_int_mul(TEMP(0), MP_DENOM_P(b
), TEMP(0))) != MP_OK
) {
918 if ((res
= mp_int_mul(TEMP(1), MP_DENOM_P(a
), TEMP(1))) != MP_OK
) {
921 if ((res
= (comb_f
)(TEMP(0), TEMP(1), MP_NUMER_P(c
))) != MP_OK
) {
925 res
= mp_int_mul(MP_DENOM_P(a
), MP_DENOM_P(b
), MP_DENOM_P(c
));
928 while (--last
>= 0) {
929 mp_int_clear(TEMP(last
));
933 return s_rat_reduce(c
);
940 /* Here there be dragons */