1 /* mpq_cmp(u,v) -- Compare U, V. Return positive, zero, or negative
2 based on if U > V, U == V, or U < V.
4 Copyright 1991, 1994, 1996, 2001, 2002, 2005 Free Software Foundation, Inc.
6 This file is part of the GNU MP Library.
8 The GNU MP Library is free software; you can redistribute it and/or modify
9 it under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or (at your
11 option) any later version.
13 The GNU MP Library is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
16 License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with the GNU MP Library. If not, see http://www.gnu.org/licenses/. */
26 mpq_cmp (const MP_RAT
*op1
, const MP_RAT
*op2
)
28 mp_size_t num1_size
= op1
->_mp_num
._mp_size
;
29 mp_size_t den1_size
= op1
->_mp_den
._mp_size
;
30 mp_size_t num2_size
= op2
->_mp_num
._mp_size
;
31 mp_size_t den2_size
= op2
->_mp_den
._mp_size
;
32 mp_size_t tmp1_size
, tmp2_size
;
33 mp_ptr tmp1_ptr
, tmp2_ptr
;
38 /* need canonical signs to get right result */
39 ASSERT (den1_size
> 0);
40 ASSERT (den2_size
> 0);
46 if ((num1_size
^ num2_size
) < 0) /* I.e. are the signs different? */
49 num1_sign
= num1_size
;
50 num1_size
= ABS (num1_size
);
51 num2_size
= ABS (num2_size
);
53 tmp1_size
= num1_size
+ den2_size
;
54 tmp2_size
= num2_size
+ den1_size
;
56 /* 1. Check to see if we can tell which operand is larger by just looking at
57 the number of limbs. */
59 /* NUM1 x DEN2 is either TMP1_SIZE limbs or TMP1_SIZE-1 limbs.
60 Same for NUM1 x DEN1 with respect to TMP2_SIZE. */
61 if (tmp1_size
> tmp2_size
+ 1)
62 /* NUM1 x DEN2 is surely larger in magnitude than NUM2 x DEN1. */
64 if (tmp2_size
> tmp1_size
+ 1)
65 /* NUM1 x DEN2 is surely smaller in magnitude than NUM2 x DEN1. */
68 /* 2. Same, but compare the number of significant bits. */
71 mp_bitcnt_t bits1
, bits2
;
73 count_leading_zeros (cnt1
, op1
->_mp_num
._mp_d
[num1_size
- 1]);
74 count_leading_zeros (cnt2
, op2
->_mp_den
._mp_d
[den2_size
- 1]);
75 bits1
= tmp1_size
* GMP_NUMB_BITS
- cnt1
- cnt2
+ 2 * GMP_NAIL_BITS
;
77 count_leading_zeros (cnt1
, op2
->_mp_num
._mp_d
[num2_size
- 1]);
78 count_leading_zeros (cnt2
, op1
->_mp_den
._mp_d
[den1_size
- 1]);
79 bits2
= tmp2_size
* GMP_NUMB_BITS
- cnt1
- cnt2
+ 2 * GMP_NAIL_BITS
;
81 if (bits1
> bits2
+ 1)
83 if (bits2
> bits1
+ 1)
87 /* 3. Finally, cross multiply and compare. */
90 TMP_ALLOC_LIMBS_2 (tmp1_ptr
,tmp1_size
, tmp2_ptr
,tmp2_size
);
92 if (num1_size
>= den2_size
)
93 tmp1_size
-= 0 == mpn_mul (tmp1_ptr
,
94 op1
->_mp_num
._mp_d
, num1_size
,
95 op2
->_mp_den
._mp_d
, den2_size
);
97 tmp1_size
-= 0 == mpn_mul (tmp1_ptr
,
98 op2
->_mp_den
._mp_d
, den2_size
,
99 op1
->_mp_num
._mp_d
, num1_size
);
101 if (num2_size
>= den1_size
)
102 tmp2_size
-= 0 == mpn_mul (tmp2_ptr
,
103 op2
->_mp_num
._mp_d
, num2_size
,
104 op1
->_mp_den
._mp_d
, den1_size
);
106 tmp2_size
-= 0 == mpn_mul (tmp2_ptr
,
107 op1
->_mp_den
._mp_d
, den1_size
,
108 op2
->_mp_num
._mp_d
, num2_size
);
111 cc
= tmp1_size
- tmp2_size
!= 0
112 ? tmp1_size
- tmp2_size
: mpn_cmp (tmp1_ptr
, tmp2_ptr
, tmp1_size
);
114 return num1_sign
< 0 ? -cc
: cc
;