Home | History | Annotate | Line # | Download | only in mpq
cmp_ui.c revision 1.1.1.1.2.1
      1          1.1   mrg /* mpq_cmp_ui(u,vn,vd) -- Compare U with Vn/Vd.  Return positive, zero, or
      2          1.1   mrg    negative based on if U > V, U == V, or U < V.  Vn and Vd may have
      3          1.1   mrg    common factors.
      4          1.1   mrg 
      5          1.1   mrg Copyright 1993, 1994, 1996, 2000, 2001, 2002, 2003, 2005 Free Software
      6          1.1   mrg Foundation, Inc.
      7          1.1   mrg 
      8          1.1   mrg This file is part of the GNU MP Library.
      9          1.1   mrg 
     10          1.1   mrg The GNU MP Library is free software; you can redistribute it and/or modify
     11          1.1   mrg it under the terms of the GNU Lesser General Public License as published by
     12          1.1   mrg the Free Software Foundation; either version 3 of the License, or (at your
     13          1.1   mrg option) any later version.
     14          1.1   mrg 
     15          1.1   mrg The GNU MP Library is distributed in the hope that it will be useful, but
     16          1.1   mrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
     17          1.1   mrg or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
     18          1.1   mrg License for more details.
     19          1.1   mrg 
     20          1.1   mrg You should have received a copy of the GNU Lesser General Public License
     21          1.1   mrg along with the GNU MP Library.  If not, see http://www.gnu.org/licenses/.  */
     22          1.1   mrg 
     23          1.1   mrg #include "gmp.h"
     24          1.1   mrg #include "gmp-impl.h"
     25          1.1   mrg 
     26          1.1   mrg int
     27          1.1   mrg _mpq_cmp_ui (const MP_RAT *op1, unsigned long int num2, unsigned long int den2)
     28          1.1   mrg {
     29  1.1.1.1.2.1  yamt   mp_size_t num1_size = SIZ(NUM(op1));
     30  1.1.1.1.2.1  yamt   mp_size_t den1_size = SIZ(DEN(op1));
     31          1.1   mrg   mp_size_t tmp1_size, tmp2_size;
     32          1.1   mrg   mp_ptr tmp1_ptr, tmp2_ptr;
     33          1.1   mrg   mp_limb_t cy_limb;
     34          1.1   mrg   int cc;
     35          1.1   mrg   TMP_DECL;
     36          1.1   mrg 
     37          1.1   mrg #if GMP_NAIL_BITS != 0
     38          1.1   mrg   if ((num2 | den2) > GMP_NUMB_MAX)
     39          1.1   mrg     {
     40          1.1   mrg       mpq_t op2;
     41          1.1   mrg       mpq_init (op2);
     42          1.1   mrg       mpz_set_ui (mpq_numref (op2), num2);
     43          1.1   mrg       mpz_set_ui (mpq_denref (op2), den2);
     44          1.1   mrg       cc = mpq_cmp (op1, op2);
     45          1.1   mrg       mpq_clear (op2);
     46          1.1   mrg       return cc;
     47          1.1   mrg     }
     48          1.1   mrg #endif
     49          1.1   mrg 
     50          1.1   mrg   /* need canonical sign to get right result */
     51          1.1   mrg   ASSERT (den1_size > 0);
     52          1.1   mrg 
     53  1.1.1.1.2.1  yamt   if (UNLIKELY (den2 == 0))
     54          1.1   mrg     DIVIDE_BY_ZERO;
     55          1.1   mrg 
     56          1.1   mrg   if (num1_size == 0)
     57          1.1   mrg     return -(num2 != 0);
     58          1.1   mrg   if (num1_size < 0)
     59          1.1   mrg     return num1_size;
     60          1.1   mrg   if (num2 == 0)
     61          1.1   mrg     return num1_size;
     62          1.1   mrg 
     63          1.1   mrg   /* NUM1 x DEN2 is either TMP1_SIZE limbs or TMP1_SIZE-1 limbs.
     64          1.1   mrg      Same for NUM1 x DEN1 with respect to TMP2_SIZE.  */
     65          1.1   mrg   if (num1_size > den1_size + 1)
     66          1.1   mrg     /* NUM1 x DEN2 is surely larger in magnitude than NUM2 x DEN1.  */
     67          1.1   mrg     return num1_size;
     68          1.1   mrg   if (den1_size > num1_size + 1)
     69          1.1   mrg     /* NUM1 x DEN2 is surely smaller in magnitude than NUM2 x DEN1.  */
     70          1.1   mrg     return -num1_size;
     71          1.1   mrg 
     72          1.1   mrg   TMP_MARK;
     73          1.1   mrg   tmp1_ptr = TMP_ALLOC_LIMBS (num1_size + 1);
     74          1.1   mrg   tmp2_ptr = TMP_ALLOC_LIMBS (den1_size + 1);
     75          1.1   mrg 
     76  1.1.1.1.2.1  yamt   cy_limb = mpn_mul_1 (tmp1_ptr, PTR(NUM(op1)), num1_size,
     77          1.1   mrg                        (mp_limb_t) den2);
     78          1.1   mrg   tmp1_ptr[num1_size] = cy_limb;
     79          1.1   mrg   tmp1_size = num1_size + (cy_limb != 0);
     80          1.1   mrg 
     81  1.1.1.1.2.1  yamt   cy_limb = mpn_mul_1 (tmp2_ptr, PTR(DEN(op1)), den1_size,
     82          1.1   mrg                        (mp_limb_t) num2);
     83          1.1   mrg   tmp2_ptr[den1_size] = cy_limb;
     84          1.1   mrg   tmp2_size = den1_size + (cy_limb != 0);
     85          1.1   mrg 
     86          1.1   mrg   cc = tmp1_size - tmp2_size != 0
     87          1.1   mrg     ? tmp1_size - tmp2_size : mpn_cmp (tmp1_ptr, tmp2_ptr, tmp1_size);
     88          1.1   mrg   TMP_FREE;
     89          1.1   mrg   return cc;
     90          1.1   mrg }
     91