summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorthevenyp <thevenyp@280ebfd0-de03-0410-8827-d642c229c3f4>2008-02-27 11:13:18 +0000
committerthevenyp <thevenyp@280ebfd0-de03-0410-8827-d642c229c3f4>2008-02-27 11:13:18 +0000
commit4eef2a6de0affc21d70c074f35d0a2e5d17b60d0 (patch)
tree086892836c664d0bab04fbcf58783ce7a744d4ba
parenta53b5f84e27622e106289bd7f7369aa87bc4eb10 (diff)
downloadmpfr-4eef2a6de0affc21d70c074f35d0a2e5d17b60d0.tar.gz
add_d.c, div_d.c, sub_d.c, d_div.c, d_sub.c: restore flags in case of exception. This fixes the bug revealed by MPFR_SUSPICIOUS_OVERFLOW
tests/tadd_d.c, tests/tsub_d.c, tests/tdiv_d.c, tests/tmul_d.c, tests/td_sub.c, tests/td_div.c, test/tmul_d.c: add checks for exception flags and ternary value git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@5322 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r--add_d.c4
-rw-r--r--d_div.c4
-rw-r--r--d_sub.c4
-rw-r--r--div_d.c4
-rw-r--r--sub_d.c4
-rw-r--r--tests/tadd_d.c22
-rw-r--r--tests/td_div.c29
-rw-r--r--tests/td_sub.c22
-rw-r--r--tests/tdiv_d.c27
-rw-r--r--tests/tmul_d.c31
-rw-r--r--tests/tsub_d.c22
11 files changed, 124 insertions, 49 deletions
diff --git a/add_d.c b/add_d.c
index 411ec422b..cc6ca099d 100644
--- a/add_d.c
+++ b/add_d.c
@@ -39,8 +39,10 @@ mpfr_add_d (mpfr_ptr a, mpfr_srcptr b, double c, mp_rnd_t rnd_mode)
inexact = mpfr_set_d (d, c, rnd_mode);
MPFR_ASSERTN (inexact == 0);
+ mpfr_clear_flags ();
inexact = mpfr_add (a, b, d, rnd_mode);
- if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (a)))
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (a)
+ || (__gmpfr_flags & MPFR_FLAGS_ALL)))
{
MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
}
diff --git a/d_div.c b/d_div.c
index 243d59b37..614455499 100644
--- a/d_div.c
+++ b/d_div.c
@@ -39,8 +39,10 @@ mpfr_d_div (mpfr_ptr a, double b, mpfr_srcptr c, mp_rnd_t rnd_mode)
inexact = mpfr_set_d (d, b, rnd_mode);
MPFR_ASSERTN (inexact == 0);
+ mpfr_clear_flags ();
inexact = mpfr_div (a, d, c, rnd_mode);
- if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (a)))
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (a)
+ || (__gmpfr_flags & MPFR_FLAGS_ALL)))
{
MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
}
diff --git a/d_sub.c b/d_sub.c
index ff55d53fa..3da9d8ee3 100644
--- a/d_sub.c
+++ b/d_sub.c
@@ -39,8 +39,10 @@ mpfr_d_sub (mpfr_ptr a, double b, mpfr_srcptr c, mp_rnd_t rnd_mode)
inexact = mpfr_set_d (d, b, rnd_mode);
MPFR_ASSERTN (inexact == 0);
+ mpfr_clear_flags ();
inexact = mpfr_sub (a, d, c, rnd_mode);
- if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (a)))
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (a)
+ || (__gmpfr_flags & MPFR_FLAGS_ALL)))
{
MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
}
diff --git a/div_d.c b/div_d.c
index a79525485..867ca663b 100644
--- a/div_d.c
+++ b/div_d.c
@@ -39,8 +39,10 @@ mpfr_div_d (mpfr_ptr a, mpfr_srcptr b, double c, mp_rnd_t rnd_mode)
inexact = mpfr_set_d (d, c, rnd_mode);
MPFR_ASSERTN (inexact == 0);
+ mpfr_clear_flags ();
inexact = mpfr_div (a, b, d, rnd_mode);
- if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (a)))
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (a)
+ || (__gmpfr_flags & MPFR_FLAGS_ALL)))
{
MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
}
diff --git a/sub_d.c b/sub_d.c
index 771bf730a..35a9f8d28 100644
--- a/sub_d.c
+++ b/sub_d.c
@@ -39,8 +39,10 @@ mpfr_sub_d (mpfr_ptr a, mpfr_srcptr b, double c, mp_rnd_t rnd_mode)
inexact = mpfr_set_d (d, c, rnd_mode);
MPFR_ASSERTN (inexact == 0);
+ mpfr_clear_flags ();
inexact = mpfr_sub (a, b, d, rnd_mode);
- if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (a)))
+ if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (a)
+ || (__gmpfr_flags & MPFR_FLAGS_ALL)))
{
MPFR_SAVE_EXPO_UPDATE_FLAGS (expo, __gmpfr_flags);
}
diff --git a/tests/tadd_d.c b/tests/tadd_d.c
index 09b8f0075..88305dcd1 100644
--- a/tests/tadd_d.c
+++ b/tests/tadd_d.c
@@ -93,26 +93,36 @@ static void
check_nans (void)
{
mpfr_t x, y;
+ int inexact;
mpfr_init2 (x, 123);
mpfr_init2 (y, 123);
/* nan + 1.0 is nan */
mpfr_set_nan (x);
- mpfr_add_d (y, x, 1.0, GMP_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_add_d (y, x, 1.0, GMP_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN ((__gmpfr_flags ^ MPFR_FLAGS_NAN) == 0);
MPFR_ASSERTN (mpfr_nan_p (y));
/* +inf + 1.0 == +inf */
mpfr_set_inf (x, 1);
- mpfr_add_d (y, x, 1.0, GMP_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_add_d (y, x, 1.0, GMP_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
MPFR_ASSERTN (mpfr_inf_p (y));
- MPFR_ASSERTN (mpfr_sgn (y) > 0);
+ MPFR_ASSERTN (MPFR_IS_POS (y));
/* -inf + 1.0 == -inf */
mpfr_set_inf (x, -1);
- mpfr_add_d (y, x, 1.0, GMP_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_add_d (y, x, 1.0, GMP_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
MPFR_ASSERTN (mpfr_inf_p (y));
- MPFR_ASSERTN (mpfr_sgn (y) < 0);
+ MPFR_ASSERTN (MPFR_IS_NEG (y));
mpfr_clear (x);
mpfr_clear (y);
@@ -124,7 +134,7 @@ check_nans (void)
#include "tgeneric.c"
int
-main (int argc, char *argv[])
+main (void)
{
tests_start_mpfr ();
diff --git a/tests/td_div.c b/tests/td_div.c
index d8103d783..9598134b5 100644
--- a/tests/td_div.c
+++ b/tests/td_div.c
@@ -32,32 +32,45 @@ static void
check_nans (void)
{
mpfr_t x, y;
+ int inexact;
mpfr_init2 (x, 123);
mpfr_init2 (y, 123);
/* 1.0 / nan is nan */
mpfr_set_nan (x);
- mpfr_d_div (y, 1.0, x, GMP_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_d_div (y, 1.0, x, GMP_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN ((__gmpfr_flags ^ MPFR_FLAGS_NAN) == 0);
MPFR_ASSERTN (mpfr_nan_p (y));
/* 1.0 / +inf == +0 */
mpfr_set_inf (x, 1);
- mpfr_d_div (y, 1.0, x, GMP_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_d_div (y, 1.0, x, GMP_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
MPFR_ASSERTN (mpfr_zero_p (y));
- MPFR_ASSERTN (MPFR_SIGN (y) > 0);
+ MPFR_ASSERTN (MPFR_IS_POS (y));
/* 1.0 / -inf == -0 */
mpfr_set_inf (x, -1);
- mpfr_d_div (y, 1.0, x, GMP_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_d_div (y, 1.0, x, GMP_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
MPFR_ASSERTN (mpfr_zero_p (y));
- MPFR_ASSERTN (MPFR_SIGN (y) < 0);
+ MPFR_ASSERTN (MPFR_IS_NEG (y));
/* 1.0 / 0 == +inf */
mpfr_set_d (x, 0.0, GMP_RNDN);
- mpfr_d_div (y, 1.0, x, GMP_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_d_div (y, 1.0, x, GMP_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
MPFR_ASSERTN (mpfr_inf_p (y));
- MPFR_ASSERTN (mpfr_sgn (y) > 0);
+ MPFR_ASSERTN (MPFR_IS_POS (y));
mpfr_clear (x);
mpfr_clear (y);
@@ -69,7 +82,7 @@ check_nans (void)
#include "tgeneric.c"
int
-main (int argc, char *argv[])
+main (void)
{
mpfr_t x, y, z;
double d;
diff --git a/tests/td_sub.c b/tests/td_sub.c
index a584d294f..5a42df048 100644
--- a/tests/td_sub.c
+++ b/tests/td_sub.c
@@ -32,26 +32,36 @@ static void
check_nans (void)
{
mpfr_t x, y;
+ int inexact;
mpfr_init2 (x, 123);
mpfr_init2 (y, 123);
/* 1.0 - nan is nan */
mpfr_set_nan (x);
- mpfr_d_sub (y, 1.0, x, GMP_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_d_sub (y, 1.0, x, GMP_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN ((__gmpfr_flags ^ MPFR_FLAGS_NAN) == 0);
MPFR_ASSERTN (mpfr_nan_p (y));
/* 1.0 - +inf == -inf */
mpfr_set_inf (x, 1);
- mpfr_d_sub (y, 1.0, x, GMP_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_d_sub (y, 1.0, x, GMP_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
MPFR_ASSERTN (mpfr_inf_p (y));
- MPFR_ASSERTN (mpfr_sgn (y) < 0);
+ MPFR_ASSERTN (MPFR_IS_NEG (y));
/* 1.0 - -inf == +inf */
mpfr_set_inf (x, -1);
- mpfr_d_sub (y, 1.0, x, GMP_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_d_sub (y, 1.0, x, GMP_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
MPFR_ASSERTN (mpfr_inf_p (y));
- MPFR_ASSERTN (mpfr_sgn (y) > 0);
+ MPFR_ASSERTN (MPFR_IS_POS (y));
mpfr_clear (x);
mpfr_clear (y);
@@ -63,7 +73,7 @@ check_nans (void)
#include "tgeneric.c"
int
-main (int argc, char *argv[])
+main (void)
{
mpfr_t x, y, z;
double d;
diff --git a/tests/tdiv_d.c b/tests/tdiv_d.c
index 46cc61f58..8c6401749 100644
--- a/tests/tdiv_d.c
+++ b/tests/tdiv_d.c
@@ -32,30 +32,43 @@ static void
check_nans (void)
{
mpfr_t x, y;
+ int inexact;
mpfr_init2 (x, 123);
mpfr_init2 (y, 123);
/* nan / 1.0 is nan */
mpfr_set_nan (x);
- mpfr_div_d (y, x, 1.0, GMP_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_div_d (y, x, 1.0, GMP_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN ((__gmpfr_flags ^ MPFR_FLAGS_NAN) == 0);
MPFR_ASSERTN (mpfr_nan_p (y));
/* +inf / 1.0 == +inf */
mpfr_set_inf (x, 1);
- mpfr_div_d (y, x, 1.0, GMP_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_div_d (y, x, 1.0, GMP_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
MPFR_ASSERTN (mpfr_inf_p (y));
- MPFR_ASSERTN (mpfr_sgn (y) > 0);
+ MPFR_ASSERTN (MPFR_IS_POS (y));
/* -inf / 1.0 == -inf */
mpfr_set_inf (x, -1);
- mpfr_div_d (y, x, 1.0, GMP_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_div_d (y, x, 1.0, GMP_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
MPFR_ASSERTN (mpfr_inf_p (y));
- MPFR_ASSERTN (mpfr_sgn (y) < 0);
+ MPFR_ASSERTN (MPFR_IS_NEG (y));
/* 0.0 / 0.0 is nan */
mpfr_set_d (x, 0.0, GMP_RNDN);
- mpfr_div_d (y, x, 0.0, GMP_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_div_d (y, x, 0.0, GMP_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN ((__gmpfr_flags ^ MPFR_FLAGS_NAN) == 0);
MPFR_ASSERTN (mpfr_nan_p (y));
mpfr_clear (x);
@@ -68,7 +81,7 @@ check_nans (void)
#include "tgeneric.c"
int
-main (int argc, char *argv[])
+main (void)
{
mpfr_t x, y, z;
double d;
diff --git a/tests/tmul_d.c b/tests/tmul_d.c
index a4a4cdfc5..7af865545 100644
--- a/tests/tmul_d.c
+++ b/tests/tmul_d.c
@@ -32,6 +32,7 @@ static void
check_nans (void)
{
mpfr_t x, y;
+ int inexact;
mpfr_init2 (x, 123);
mpfr_init2 (y, 123);
@@ -39,27 +40,35 @@ check_nans (void)
/* nan * 1.0 is nan */
mpfr_set_nan (x);
mpfr_clear_flags();
- mpfr_mul_d (y, x, 1.0, GMP_RNDN);
- MPFR_ASSERTN (mpfr_nan_p (y) && mpfr_nanflag_p());
+ inexact = mpfr_mul_d (y, x, 1.0, GMP_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN ((__gmpfr_flags ^ MPFR_FLAGS_NAN) == 0);
+ MPFR_ASSERTN (mpfr_nan_p (y));
/* +inf * 1.0 == +inf */
mpfr_set_inf (x, 1);
mpfr_clear_flags();
- mpfr_mul_d (y, x, 1.0, GMP_RNDN);
- MPFR_ASSERTN (mpfr_inf_p (y) && !mpfr_overflow_p());
- MPFR_ASSERTN (mpfr_sgn (y) > 0);
+ inexact = mpfr_mul_d (y, x, 1.0, GMP_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (MPFR_IS_POS (y));
/* +inf * 0.0 is nan */
mpfr_clear_flags();
- mpfr_mul_d (y, x, 0.0, GMP_RNDN);
- MPFR_ASSERTN (mpfr_nan_p (y) || mpfr_nanflag_p());
+ inexact = mpfr_mul_d (y, x, 0.0, GMP_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN ((__gmpfr_flags ^ MPFR_FLAGS_NAN) == 0);
+ MPFR_ASSERTN (mpfr_nan_p (y));
/* -inf * 1.0 == -inf */
mpfr_set_inf (x, -1);
mpfr_clear_flags();
- mpfr_mul_d (y, x, 1.0, GMP_RNDN);
- MPFR_ASSERTN (mpfr_inf_p (y) && !mpfr_overflow_p());
- MPFR_ASSERTN (mpfr_sgn (y) < 0);
+ inexact = mpfr_mul_d (y, x, 1.0, GMP_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
+ MPFR_ASSERTN (mpfr_inf_p (y));
+ MPFR_ASSERTN (MPFR_IS_NEG (y));
mpfr_clear (x);
mpfr_clear (y);
@@ -71,7 +80,7 @@ check_nans (void)
#include "tgeneric.c"
int
-main (int argc, char *argv[])
+main (void)
{
mpfr_t x, y, z;
double d;
diff --git a/tests/tsub_d.c b/tests/tsub_d.c
index 036ae9c43..61b52dabb 100644
--- a/tests/tsub_d.c
+++ b/tests/tsub_d.c
@@ -32,26 +32,36 @@ static void
check_nans (void)
{
mpfr_t x, y;
+ int inexact;
mpfr_init2 (x, 123);
mpfr_init2 (y, 123);
/* nan - 1.0 is nan */
mpfr_set_nan (x);
- mpfr_sub_d (y, x, 1.0, GMP_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_sub_d (y, x, 1.0, GMP_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN ((__gmpfr_flags ^ MPFR_FLAGS_NAN) == 0);
MPFR_ASSERTN (mpfr_nan_p (y));
/* +inf - 1.0 == +inf */
mpfr_set_inf (x, 1);
- mpfr_sub_d (y, x, 1.0, GMP_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_sub_d (y, x, 1.0, GMP_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
MPFR_ASSERTN (mpfr_inf_p (y));
- MPFR_ASSERTN (mpfr_sgn (y) > 0);
+ MPFR_ASSERTN (MPFR_IS_POS (y));
/* -inf - 1.0 == -inf */
mpfr_set_inf (x, -1);
- mpfr_sub_d (y, x, 1.0, GMP_RNDN);
+ mpfr_clear_flags ();
+ inexact = mpfr_sub_d (y, x, 1.0, GMP_RNDN);
+ MPFR_ASSERTN (inexact == 0);
+ MPFR_ASSERTN (__gmpfr_flags == 0);
MPFR_ASSERTN (mpfr_inf_p (y));
- MPFR_ASSERTN (mpfr_sgn (y) < 0);
+ MPFR_ASSERTN (MPFR_IS_NEG (y));
mpfr_clear (x);
mpfr_clear (y);
@@ -63,7 +73,7 @@ check_nans (void)
#include "tgeneric.c"
int
-main (int argc, char *argv[])
+main (void)
{
mpfr_t x, y, z;
double d;