1 /* mpfr_nextabove, mpfr_nextbelow, mpfr_nexttoward -- next representable
4 Copyright 1999, 2001-2015 Free Software Foundation, Inc.
5 Contributed by the AriC and Caramel projects, INRIA.
7 This file is part of the GNU MPFR Library.
9 The GNU MPFR Library is free software; you can redistribute it and/or modify
10 it under the terms of the GNU Lesser General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or (at your
12 option) any later version.
14 The GNU MPFR Library is distributed in the hope that it will be useful, but
15 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
17 License for more details.
19 You should have received a copy of the GNU Lesser General Public License
20 along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
21 http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
22 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
24 #include "mpfr-impl.h"
27 mpfr_nexttozero (mpfr_ptr x
)
29 if (MPFR_UNLIKELY(MPFR_IS_INF(x
)))
31 mpfr_setmax (x
, __gmpfr_emax
);
34 else if (MPFR_UNLIKELY( MPFR_IS_ZERO(x
) ))
37 mpfr_setmin (x
, __gmpfr_emin
);
45 xn
= MPFR_LIMB_SIZE (x
);
46 MPFR_UNSIGNED_MINUS_MODULO (sh
, MPFR_PREC(x
));
48 mpn_sub_1 (xp
, xp
, xn
, MPFR_LIMB_ONE
<< sh
);
49 if (MPFR_UNLIKELY( MPFR_LIMB_MSB(xp
[xn
-1]) == 0) )
50 { /* was an exact power of two: not normalized any more */
51 mpfr_exp_t exp
= MPFR_EXP (x
);
52 if (MPFR_UNLIKELY(exp
== __gmpfr_emin
))
57 MPFR_SET_EXP (x
, exp
- 1);
58 xp
[0] = MP_LIMB_T_MAX
<< sh
;
59 for (i
= 1; i
< xn
; i
++)
60 xp
[i
] = MP_LIMB_T_MAX
;
67 mpfr_nexttoinf (mpfr_ptr x
)
69 if (MPFR_UNLIKELY(MPFR_IS_INF(x
)))
71 else if (MPFR_UNLIKELY(MPFR_IS_ZERO(x
)))
72 mpfr_setmin (x
, __gmpfr_emin
);
79 xn
= MPFR_LIMB_SIZE (x
);
80 MPFR_UNSIGNED_MINUS_MODULO (sh
, MPFR_PREC(x
));
82 if (MPFR_UNLIKELY( mpn_add_1 (xp
, xp
, xn
, MPFR_LIMB_ONE
<< sh
)) )
85 mpfr_exp_t exp
= MPFR_EXP (x
);
86 if (MPFR_UNLIKELY(exp
== __gmpfr_emax
))
90 MPFR_SET_EXP (x
, exp
+ 1);
91 xp
[xn
-1] = MPFR_LIMB_HIGHBIT
;
98 mpfr_nextabove (mpfr_ptr x
)
100 if (MPFR_UNLIKELY(MPFR_IS_NAN(x
)))
102 __gmpfr_flags
|= MPFR_FLAGS_NAN
;
112 mpfr_nextbelow (mpfr_ptr x
)
114 if (MPFR_UNLIKELY(MPFR_IS_NAN(x
)))
116 __gmpfr_flags
|= MPFR_FLAGS_NAN
;
127 mpfr_nexttoward (mpfr_ptr x
, mpfr_srcptr y
)
131 if (MPFR_UNLIKELY(MPFR_IS_NAN(x
)))
133 __gmpfr_flags
|= MPFR_FLAGS_NAN
;
136 else if (MPFR_UNLIKELY(MPFR_IS_NAN(x
) || MPFR_IS_NAN(y
)))
139 __gmpfr_flags
|= MPFR_FLAGS_NAN
;