1*86d7f5d3SJohn Marino /* mpq_inv(dest,src) -- invert a rational number, i.e. set DEST to SRC
2*86d7f5d3SJohn Marino with the numerator and denominator swapped.
3*86d7f5d3SJohn Marino
4*86d7f5d3SJohn Marino Copyright 1991, 1994, 1995, 2000, 2001 Free Software Foundation, Inc.
5*86d7f5d3SJohn Marino
6*86d7f5d3SJohn Marino This file is part of the GNU MP Library.
7*86d7f5d3SJohn Marino
8*86d7f5d3SJohn Marino The GNU MP Library is free software; you can redistribute it and/or modify
9*86d7f5d3SJohn Marino it under the terms of the GNU Lesser General Public License as published by
10*86d7f5d3SJohn Marino the Free Software Foundation; either version 3 of the License, or (at your
11*86d7f5d3SJohn Marino option) any later version.
12*86d7f5d3SJohn Marino
13*86d7f5d3SJohn Marino The GNU MP Library is distributed in the hope that it will be useful, but
14*86d7f5d3SJohn Marino WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15*86d7f5d3SJohn Marino or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16*86d7f5d3SJohn Marino License for more details.
17*86d7f5d3SJohn Marino
18*86d7f5d3SJohn Marino You should have received a copy of the GNU Lesser General Public License
19*86d7f5d3SJohn Marino along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
20*86d7f5d3SJohn Marino
21*86d7f5d3SJohn Marino #include "gmp.h"
22*86d7f5d3SJohn Marino #include "gmp-impl.h"
23*86d7f5d3SJohn Marino
24*86d7f5d3SJohn Marino void
mpq_inv(MP_RAT * dest,const MP_RAT * src)25*86d7f5d3SJohn Marino mpq_inv (MP_RAT *dest, const MP_RAT *src)
26*86d7f5d3SJohn Marino {
27*86d7f5d3SJohn Marino mp_size_t num_size = src->_mp_num._mp_size;
28*86d7f5d3SJohn Marino mp_size_t den_size = src->_mp_den._mp_size;
29*86d7f5d3SJohn Marino
30*86d7f5d3SJohn Marino if (num_size == 0)
31*86d7f5d3SJohn Marino DIVIDE_BY_ZERO;
32*86d7f5d3SJohn Marino
33*86d7f5d3SJohn Marino if (num_size < 0)
34*86d7f5d3SJohn Marino {
35*86d7f5d3SJohn Marino num_size = -num_size;
36*86d7f5d3SJohn Marino den_size = -den_size;
37*86d7f5d3SJohn Marino }
38*86d7f5d3SJohn Marino dest->_mp_den._mp_size = num_size;
39*86d7f5d3SJohn Marino dest->_mp_num._mp_size = den_size;
40*86d7f5d3SJohn Marino
41*86d7f5d3SJohn Marino /* If dest == src we may just swap the numerator and denominator, but
42*86d7f5d3SJohn Marino we have to ensure the new denominator is positive. */
43*86d7f5d3SJohn Marino
44*86d7f5d3SJohn Marino if (dest == src)
45*86d7f5d3SJohn Marino {
46*86d7f5d3SJohn Marino mp_size_t alloc = dest->_mp_num._mp_alloc;
47*86d7f5d3SJohn Marino mp_ptr limb_ptr = dest->_mp_num._mp_d;
48*86d7f5d3SJohn Marino
49*86d7f5d3SJohn Marino dest->_mp_num._mp_alloc = dest->_mp_den._mp_alloc;
50*86d7f5d3SJohn Marino dest->_mp_num._mp_d = dest->_mp_den._mp_d;
51*86d7f5d3SJohn Marino
52*86d7f5d3SJohn Marino dest->_mp_den._mp_alloc = alloc;
53*86d7f5d3SJohn Marino dest->_mp_den._mp_d = limb_ptr;
54*86d7f5d3SJohn Marino }
55*86d7f5d3SJohn Marino else
56*86d7f5d3SJohn Marino {
57*86d7f5d3SJohn Marino den_size = ABS (den_size);
58*86d7f5d3SJohn Marino if (dest->_mp_num._mp_alloc < den_size)
59*86d7f5d3SJohn Marino _mpz_realloc (&(dest->_mp_num), den_size);
60*86d7f5d3SJohn Marino
61*86d7f5d3SJohn Marino if (dest->_mp_den._mp_alloc < num_size)
62*86d7f5d3SJohn Marino _mpz_realloc (&(dest->_mp_den), num_size);
63*86d7f5d3SJohn Marino
64*86d7f5d3SJohn Marino MPN_COPY (dest->_mp_num._mp_d, src->_mp_den._mp_d, den_size);
65*86d7f5d3SJohn Marino MPN_COPY (dest->_mp_den._mp_d, src->_mp_num._mp_d, num_size);
66*86d7f5d3SJohn Marino }
67*86d7f5d3SJohn Marino }
68