diff options
Diffstat (limited to 'src/get_si.c')
-rw-r--r-- | src/get_si.c | 15 |
1 files changed, 13 insertions, 2 deletions
diff --git a/src/get_si.c b/src/get_si.c index 134874c30..3afad5839 100644 --- a/src/get_si.c +++ b/src/get_si.c @@ -28,6 +28,7 @@ mpfr_get_si (mpfr_srcptr f, mpfr_rnd_t rnd) mpfr_prec_t prec; long s; mpfr_t x; + MPFR_SAVE_EXPO_DECL (expo); if (MPFR_UNLIKELY (!mpfr_fits_slong_p (f, rnd))) { @@ -39,14 +40,22 @@ mpfr_get_si (mpfr_srcptr f, mpfr_rnd_t rnd) if (MPFR_IS_ZERO (f)) return (long) 0; - /* determine prec of long */ - for (s = LONG_MIN, prec = 0; s != 0; s /= 2, prec++) + /* Determine the precision of long. |LONG_MIN| may have one more bit + as an integer, but in this case, this is a power of 2, thus fits + in a precision-prec floating-point number. */ + for (s = LONG_MAX, prec = 0; s != 0; s /= 2, prec++) { } + MPFR_SAVE_EXPO_MARK (expo); + /* first round to prec bits */ mpfr_init2 (x, prec); mpfr_rint (x, f, rnd); + /* The flags from mpfr_rint are the wanted ones. In particular, + it sets the inexact flag when necessary. */ + MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags); + /* warning: if x=0, taking its exponent is illegal */ if (MPFR_UNLIKELY (MPFR_IS_ZERO(x))) s = 0; @@ -65,5 +74,7 @@ mpfr_get_si (mpfr_srcptr f, mpfr_rnd_t rnd) mpfr_clear (x); + MPFR_SAVE_EXPO_FREE (expo); + return s; } |