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