summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2015-06-05 01:30:20 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2015-06-05 01:30:20 +0000
commitcb809ea1cb721e03b022a223db55326a27967e7b (patch)
tree4dd3f3272cef6809086b4a19b8e124757e811caf
parent056d175cec64ca98d8765204b98be00b5000bebd (diff)
downloadmpfr-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.c20
-rw-r--r--src/ui_sub.c22
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);
}
}