1 /* mpfr_nextabove, mpfr_nextbelow, mpfr_nexttoward -- next representable
4 Copyright 1999, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 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;