diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2015-06-05 01:30:20 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2015-06-05 01:30:20 +0000 |
commit | cb809ea1cb721e03b022a223db55326a27967e7b (patch) | |
tree | 4dd3f3272cef6809086b4a19b8e124757e811caf | |
parent | 056d175cec64ca98d8765204b98be00b5000bebd (diff) | |
download | mpfr-cb809ea1cb721e03b022a223db55326a27967e7b.tar.gz |
[src/{ui_div.c,ui_sub.c}] Correction for reduced exponent range.
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@9514 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r-- | src/ui_div.c | 20 | ||||
-rw-r--r-- | src/ui_sub.c | 22 |
2 files changed, 31 insertions, 11 deletions
diff --git a/src/ui_div.c b/src/ui_div.c index e127a0001..adb7c07d4 100644 --- a/src/ui_div.c +++ b/src/ui_div.c @@ -28,10 +28,6 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., int mpfr_ui_div (mpfr_ptr y, unsigned long int u, mpfr_srcptr x, mpfr_rnd_t rnd_mode) { - mpfr_t uu; - mp_limb_t up[1]; - int cnt; - MPFR_LOG_FUNC (("u=%lu x[%Pu]=%.*Rg rnd=%d", u, mpfr_get_prec(x), mpfr_log_prec, x, rnd_mode), @@ -71,12 +67,26 @@ mpfr_ui_div (mpfr_ptr y, unsigned long int u, mpfr_srcptr x, mpfr_rnd_t rnd_mode } else if (MPFR_LIKELY(u != 0)) { + mpfr_t uu; + mp_limb_t up[1]; + int cnt; + int inex; + + MPFR_SAVE_EXPO_DECL (expo); + MPFR_TMP_INIT1(up, uu, GMP_NUMB_BITS); MPFR_ASSERTN(u == (mp_limb_t) u); count_leading_zeros(cnt, (mp_limb_t) u); up[0] = (mp_limb_t) u << cnt; + + /* Optimization note: Exponent save/restore operations may be + removed if mpfr_div works even when uu is out-of-range. */ + MPFR_SAVE_EXPO_MARK (expo); MPFR_SET_EXP (uu, GMP_NUMB_BITS - cnt); - return mpfr_div (y, uu, x, rnd_mode); + inex = mpfr_div (y, uu, x, rnd_mode); + MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags); + MPFR_SAVE_EXPO_FREE (expo); + return mpfr_check_range (y, inex, rnd_mode); } else /* u = 0, and x != 0 */ { diff --git a/src/ui_sub.c b/src/ui_sub.c index 2a3c1b994..bb8166ef2 100644 --- a/src/ui_sub.c +++ b/src/ui_sub.c @@ -26,10 +26,6 @@ http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., int mpfr_ui_sub (mpfr_ptr y, unsigned long int u, mpfr_srcptr x, mpfr_rnd_t rnd_mode) { - mpfr_t uu; - mp_limb_t up[1]; - int cnt; - MPFR_LOG_FUNC (("u=%lu x[%Pu]=%.*Rg rnd=%d", u, mpfr_get_prec(x), mpfr_log_prec, x, rnd_mode), @@ -58,11 +54,25 @@ mpfr_ui_sub (mpfr_ptr y, unsigned long int u, mpfr_srcptr x, mpfr_rnd_t rnd_mode } else { + mpfr_t uu; + mp_limb_t up[1]; + int cnt; + int inex; + + MPFR_SAVE_EXPO_DECL (expo); + MPFR_TMP_INIT1 (up, uu, GMP_NUMB_BITS); MPFR_ASSERTN(u == (mp_limb_t) u); count_leading_zeros (cnt, (mp_limb_t) u); - *up = (mp_limb_t) u << cnt; + up[0] = (mp_limb_t) u << cnt; + + /* Optimization note: Exponent save/restore operations may be + removed if mpfr_sub works even when uu is out-of-range. */ + MPFR_SAVE_EXPO_MARK (expo); MPFR_SET_EXP (uu, GMP_NUMB_BITS - cnt); - return mpfr_sub (y, uu, x, rnd_mode); + inex = mpfr_sub (y, uu, x, rnd_mode); + MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags); + MPFR_SAVE_EXPO_FREE (expo); + return mpfr_check_range(y, inex, rnd_mode); } } |