1274074Sngie/* mpq_inv(dest,src) -- invert a rational number, i.e. set DEST to SRC 2274074Sngie with the numerator and denominator swapped. 3274074Sngie 4274074SngieCopyright 1991, 1994, 1995, 2000, 2001 Free Software Foundation, Inc. 5274074Sngie 6292278SngieThis file is part of the GNU MP Library. 7274074Sngie 8292278SngieThe GNU MP Library is free software; you can redistribute it and/or modify 9274074Sngieit under the terms of the GNU Lesser General Public License as published by 10292278Sngiethe Free Software Foundation; either version 3 of the License, or (at your 11292278Sngieoption) any later version. 12274074Sngie 13274074SngieThe GNU MP Library is distributed in the hope that it will be useful, but 14274074SngieWITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15274074Sngieor FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 16274074SngieLicense for more details. 17274074Sngie 18274074SngieYou should have received a copy of the GNU Lesser General Public License 19274074Sngiealong with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */ 20274074Sngie 21274074Sngie#include "gmp.h" 22274074Sngie#include "gmp-impl.h" 23274074Sngie 24274074Sngievoid 25274074Sngiempq_inv (MP_RAT *dest, const MP_RAT *src) 26274074Sngie{ 27274074Sngie mp_size_t num_size = src->_mp_num._mp_size; 28274074Sngie mp_size_t den_size = src->_mp_den._mp_size; 29274074Sngie 30274074Sngie if (num_size == 0) 31274074Sngie DIVIDE_BY_ZERO; 32274074Sngie 33274074Sngie if (num_size < 0) 34274074Sngie { 35274074Sngie num_size = -num_size; 36274074Sngie den_size = -den_size; 37274074Sngie } 38274074Sngie dest->_mp_den._mp_size = num_size; 39274074Sngie dest->_mp_num._mp_size = den_size; 40274074Sngie 41274074Sngie /* If dest == src we may just swap the numerator and denominator, but 42274074Sngie we have to ensure the new denominator is positive. */ 43 44 if (dest == src) 45 { 46 mp_size_t alloc = dest->_mp_num._mp_alloc; 47 mp_ptr limb_ptr = dest->_mp_num._mp_d; 48 49 dest->_mp_num._mp_alloc = dest->_mp_den._mp_alloc; 50 dest->_mp_num._mp_d = dest->_mp_den._mp_d; 51 52 dest->_mp_den._mp_alloc = alloc; 53 dest->_mp_den._mp_d = limb_ptr; 54 } 55 else 56 { 57 den_size = ABS (den_size); 58 if (dest->_mp_num._mp_alloc < den_size) 59 _mpz_realloc (&(dest->_mp_num), den_size); 60 61 if (dest->_mp_den._mp_alloc < num_size) 62 _mpz_realloc (&(dest->_mp_den), num_size); 63 64 MPN_COPY (dest->_mp_num._mp_d, src->_mp_den._mp_d, den_size); 65 MPN_COPY (dest->_mp_den._mp_d, src->_mp_num._mp_d, num_size); 66 } 67} 68