1d59437c0Smrg /* mpfr_cmp_ui_2exp -- compare a floating-point number with an unsigned
2d59437c0Smrg machine integer multiplied by a power of 2
3d59437c0Smrg
4*ba125506Smrg Copyright 1999, 2001-2004, 2006-2023 Free Software Foundation, Inc.
5efdec83bSmrg Contributed by the AriC and Caramba projects, INRIA.
6d59437c0Smrg
7d59437c0Smrg This file is part of the GNU MPFR Library.
8d59437c0Smrg
9d59437c0Smrg The GNU MPFR Library is free software; you can redistribute it and/or modify
10d59437c0Smrg it under the terms of the GNU Lesser General Public License as published by
11d59437c0Smrg the Free Software Foundation; either version 3 of the License, or (at your
12d59437c0Smrg option) any later version.
13d59437c0Smrg
14d59437c0Smrg The GNU MPFR Library is distributed in the hope that it will be useful, but
15d59437c0Smrg WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16d59437c0Smrg or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17d59437c0Smrg License for more details.
18d59437c0Smrg
19d59437c0Smrg You should have received a copy of the GNU Lesser General Public License
20d59437c0Smrg along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
212ba2404bSmrg https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
22d59437c0Smrg 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
23d59437c0Smrg
24d59437c0Smrg #define MPFR_NEED_LONGLONG_H
25d59437c0Smrg #include "mpfr-impl.h"
26d59437c0Smrg
27d59437c0Smrg /* returns a positive value if b > i*2^f,
28d59437c0Smrg a negative value if b < i*2^f,
29d59437c0Smrg zero if b = i*2^f.
30d59437c0Smrg b must not be NaN
31d59437c0Smrg */
32d59437c0Smrg
33d59437c0Smrg int
mpfr_cmp_ui_2exp(mpfr_srcptr b,unsigned long int i,mpfr_exp_t f)34d59437c0Smrg mpfr_cmp_ui_2exp (mpfr_srcptr b, unsigned long int i, mpfr_exp_t f)
35d59437c0Smrg {
36d59437c0Smrg if (MPFR_UNLIKELY( MPFR_IS_SINGULAR(b) ))
37d59437c0Smrg {
38d59437c0Smrg if (MPFR_IS_NAN (b))
39d59437c0Smrg {
40299c6f0cSmrg MPFR_SET_ERANGEFLAG ();
41d59437c0Smrg return 0;
42d59437c0Smrg }
43d59437c0Smrg else if (MPFR_IS_INF(b))
44d59437c0Smrg return MPFR_INT_SIGN (b);
45d59437c0Smrg else /* since b cannot be NaN, b=0 here */
46d59437c0Smrg return i != 0 ? -1 : 0;
47d59437c0Smrg }
48d59437c0Smrg
49d59437c0Smrg if (MPFR_IS_NEG (b))
50d59437c0Smrg return -1;
51d59437c0Smrg /* now b > 0 */
52d59437c0Smrg else if (MPFR_UNLIKELY(i == 0))
53d59437c0Smrg return 1;
54d59437c0Smrg else /* b > 0, i > 0 */
552ba2404bSmrg #ifdef MPFR_LONG_WITHIN_LIMB
56d59437c0Smrg {
57d59437c0Smrg mpfr_exp_t e;
58d59437c0Smrg int k;
59d59437c0Smrg mp_size_t bn;
60d59437c0Smrg mp_limb_t c, *bp;
61d59437c0Smrg
62d59437c0Smrg /* i must be representable in a mp_limb_t */
63d59437c0Smrg MPFR_ASSERTN(i == (mp_limb_t) i);
64d59437c0Smrg
65d59437c0Smrg e = MPFR_GET_EXP (b); /* 2^(e-1) <= b < 2^e */
66d59437c0Smrg if (e <= f)
67d59437c0Smrg return -1;
68d59437c0Smrg if (f < MPFR_EMAX_MAX - GMP_NUMB_BITS &&
69d59437c0Smrg e > f + GMP_NUMB_BITS)
70d59437c0Smrg return 1;
71d59437c0Smrg
72d59437c0Smrg /* now f < e <= f + GMP_NUMB_BITS */
73d59437c0Smrg c = (mp_limb_t) i;
74d59437c0Smrg count_leading_zeros(k, c);
75d59437c0Smrg if ((int) (e - f) > GMP_NUMB_BITS - k)
76d59437c0Smrg return 1;
77d59437c0Smrg if ((int) (e - f) < GMP_NUMB_BITS - k)
78d59437c0Smrg return -1;
79d59437c0Smrg
80d59437c0Smrg /* now b and i*2^f have the same exponent */
81d59437c0Smrg c <<= k;
82d59437c0Smrg bn = (MPFR_PREC(b) - 1) / GMP_NUMB_BITS;
83d59437c0Smrg bp = MPFR_MANT(b);
84d59437c0Smrg if (bp[bn] > c)
85d59437c0Smrg return 1;
86d59437c0Smrg if (bp[bn] < c)
87d59437c0Smrg return -1;
88d59437c0Smrg
89d59437c0Smrg /* most significant limbs agree, check remaining limbs from b */
90d59437c0Smrg while (bn > 0)
91d59437c0Smrg if (bp[--bn] != 0)
92d59437c0Smrg return 1;
93d59437c0Smrg return 0;
94d59437c0Smrg }
952ba2404bSmrg #else
962ba2404bSmrg {
972ba2404bSmrg mpfr_t uu;
982ba2404bSmrg int ret;
992ba2404bSmrg MPFR_SAVE_EXPO_DECL (expo);
1002ba2404bSmrg
1012ba2404bSmrg mpfr_init2 (uu, sizeof (unsigned long) * CHAR_BIT);
1022ba2404bSmrg /* Warning: i*2^f might be outside the current exponent range! */
1032ba2404bSmrg MPFR_SAVE_EXPO_MARK (expo);
1042ba2404bSmrg mpfr_set_ui_2exp (uu, i, f, MPFR_RNDZ);
1052ba2404bSmrg MPFR_SAVE_EXPO_FREE (expo);
1062ba2404bSmrg ret = mpfr_cmp (b, uu);
1072ba2404bSmrg mpfr_clear (uu);
1082ba2404bSmrg return ret;
1092ba2404bSmrg }
1102ba2404bSmrg #endif /* MPFR_LONG_WITHIN_LIMB */
111d59437c0Smrg }
112d59437c0Smrg
113d59437c0Smrg #undef mpfr_cmp_ui
114d59437c0Smrg int
mpfr_cmp_ui(mpfr_srcptr b,unsigned long int i)115d59437c0Smrg mpfr_cmp_ui (mpfr_srcptr b, unsigned long int i)
116d59437c0Smrg {
117d59437c0Smrg return mpfr_cmp_ui_2exp (b, i, 0);
118d59437c0Smrg }
119