kernel/vga: Fix -Wundef.
[dragonfly.git] / contrib / gmp / mpq / cmp.c
blob1844c2970daa8757b312ac05a590c17b8946a678
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/. */
21 #include "gmp.h"
22 #include "gmp-impl.h"
23 #include "longlong.h"
25 int
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;
34 mp_size_t num1_sign;
35 int cc;
36 TMP_DECL;
38 /* need canonical signs to get right result */
39 ASSERT (den1_size > 0);
40 ASSERT (den2_size > 0);
42 if (num1_size == 0)
43 return -num2_size;
44 if (num2_size == 0)
45 return num1_size;
46 if ((num1_size ^ num2_size) < 0) /* I.e. are the signs different? */
47 return num1_size;
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. */
63 return num1_sign;
64 if (tmp2_size > tmp1_size + 1)
65 /* NUM1 x DEN2 is surely smaller in magnitude than NUM2 x DEN1. */
66 return -num1_sign;
68 /* 2. Same, but compare the number of significant bits. */
70 int cnt1, cnt2;
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)
82 return num1_sign;
83 if (bits2 > bits1 + 1)
84 return -num1_sign;
87 /* 3. Finally, cross multiply and compare. */
89 TMP_MARK;
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);
96 else
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);
105 else
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);
113 TMP_FREE;
114 return num1_sign < 0 ? -cc : cc;