summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4>2004-09-29 13:58:06 +0000
committerpelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4>2004-09-29 13:58:06 +0000
commitf2af580a8d5f41bc8fdebf7209c5a2959c83efc6 (patch)
tree049b34ab0e842b44e5d327a40a5001379d86c0fd
parentf70d2f99fa9a99f09e1f9f602efe5930c079cee6 (diff)
downloadmpfr-f2af580a8d5f41bc8fdebf7209c5a2959c83efc6.tar.gz
cmp(x,y) if x=NAN or y=NAN returns 0 and erange flag.
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@3010 280ebfd0-de03-0410-8827-d642c229c3f4
-rw-r--r--TODO6
-rw-r--r--cmp.c9
-rw-r--r--cmp_abs.c14
-rw-r--r--cmp_d.c12
-rw-r--r--cmp_si.c21
-rw-r--r--cmp_ui.c12
-rw-r--r--mpfr.texi7
-rw-r--r--tests/tcmp.c26
-rw-r--r--tests/tcmp_d.c18
-rw-r--r--tests/tcmp_ld.c19
-rw-r--r--tests/tcmp_ui.c22
-rw-r--r--tests/tcmpabs.c25
12 files changed, 153 insertions, 38 deletions
diff --git a/TODO b/TODO
index b44e679fc..c57a6faaa 100644
--- a/TODO
+++ b/TODO
@@ -69,12 +69,6 @@ Changes in existing functions:
rounding, if the round bit is 0 (resp. 1), we just have to check
round(approx-error) (resp. round(approx+error)).
-- add a flag MPFR_FLAGS_ERANGE to signal a domain error when the result
- is not a MPFR number (otherwise NaN is used both in __gmpfr_flags and
- in the result). Modify the following functions to use it:
- * Conversions MPFR -> C integer (e.g. mpfr_get_ui).
- * Comparisons when NaN is not accepted.
-
New functions to implement:
- modf (to extract integer and fractional parts), suggested by
diff --git a/cmp.c b/cmp.c
index 38c59da11..641954b32 100644
--- a/cmp.c
+++ b/cmp.c
@@ -36,9 +36,14 @@ mpfr_cmp3 (mpfr_srcptr b, mpfr_srcptr c, int s)
s = MPFR_MULT_SIGN( s , MPFR_SIGN(c) );
- if (MPFR_ARE_SINGULAR(b,c))
+ if (MPFR_ARE_SINGULAR(b, c))
{
- if (MPFR_IS_INF(b))
+ if (MPFR_IS_NAN (b) || MPFR_IS_NAN (c))
+ {
+ MPFR_SET_ERANGE ();
+ return 0;
+ }
+ else if (MPFR_IS_INF(b))
{
if (MPFR_IS_INF(c) && s == MPFR_SIGN(b) )
return 0;
diff --git a/cmp_abs.c b/cmp_abs.c
index abf792aad..8aeb628dc 100644
--- a/cmp_abs.c
+++ b/cmp_abs.c
@@ -33,17 +33,19 @@ mpfr_cmpabs (mpfr_srcptr b, mpfr_srcptr c)
if (MPFR_ARE_SINGULAR (b, c))
{
- if (MPFR_IS_INF (b))
+ if (MPFR_IS_NAN (b) || MPFR_IS_NAN (c))
+ {
+ MPFR_SET_ERANGE ();
+ return 0;
+ }
+ else if (MPFR_IS_INF (b))
return ! MPFR_IS_INF (c);
else if (MPFR_IS_INF (c))
return -1;
else if (MPFR_IS_ZERO (c))
return ! MPFR_IS_ZERO (b);
- else
- {
- MPFR_ASSERTD (MPFR_IS_ZERO (b) );
- return -1;
- }
+ else /* b == 0 */
+ return -1;
}
be = MPFR_GET_EXP (b);
diff --git a/cmp_d.c b/cmp_d.c
index 869c3d332..4426aa2ee 100644
--- a/cmp_d.c
+++ b/cmp_d.c
@@ -25,15 +25,13 @@ int
mpfr_cmp_d (mpfr_srcptr b, double d)
{
mpfr_t tmp;
- int z;
-
- MPFR_ASSERTN(!MPFR_IS_NAN(b));
+ int res;
mpfr_init2 (tmp, IEEE_DBL_MANT_DIG);
- mpfr_set_d (tmp, d, GMP_RNDN);
-
- z = mpfr_cmp (b, tmp);
+ res = mpfr_set_d (tmp, d, GMP_RNDN);
+ MPFR_ASSERTD (res == 0);
+ res = mpfr_cmp (b, tmp);
mpfr_clear (tmp);
- return z;
+ return res;
}
diff --git a/cmp_si.c b/cmp_si.c
index 0abba8795..c64d1de5d 100644
--- a/cmp_si.c
+++ b/cmp_si.c
@@ -34,16 +34,19 @@ mpfr_cmp_si_2exp (mpfr_srcptr b, long int i, mp_exp_t f)
{
int si;
- MPFR_ASSERTD(!MPFR_IS_NAN(b));
-
si = i < 0 ? -1 : 1; /* sign of i */
- if (MPFR_IS_INF(b) || (MPFR_NOTZERO(b) && MPFR_SIGN(b) != si))
- return MPFR_SIGN(b);
- /* both signs differ or b = 0 */
- else if (MPFR_IS_ZERO(b))
- return i != 0 ? -si : 0;
- else if (i == 0)
- return MPFR_SIGN(b);
+ if (MPFR_IS_SINGULAR (b))
+ {
+ if (MPFR_IS_INF(b))
+ return MPFR_INT_SIGN(b);
+ else if (MPFR_IS_ZERO(b))
+ return i != 0 ? -si : 0;
+ /* NAN */
+ MPFR_SET_ERANGE ();
+ return 0;
+ }
+ else if (MPFR_SIGN(b) != si || i == 0)
+ return MPFR_INT_SIGN (b);
else /* b and i are of same sign si */
{
mp_exp_t e;
diff --git a/cmp_ui.c b/cmp_ui.c
index b890deb83..7decd7f2b 100644
--- a/cmp_ui.c
+++ b/cmp_ui.c
@@ -34,14 +34,18 @@ mpfr_cmp_ui_2exp (mpfr_srcptr b, unsigned long int i, mp_exp_t f)
{
if (MPFR_UNLIKELY( MPFR_IS_SINGULAR(b) ))
{
- MPFR_ASSERTD (!MPFR_IS_NAN (b) );
- if (MPFR_IS_INF(b))
- return MPFR_SIGN(b);
+ if (MPFR_IS_NAN (b))
+ {
+ MPFR_SET_ERANGE ();
+ return 0;
+ }
+ else if (MPFR_IS_INF(b))
+ return MPFR_INT_SIGN (b);
else /* since b cannot be NaN, b=0 here */
return i != 0 ? -1 : 0;
}
- if (MPFR_IS_NEG(b))
+ if (MPFR_IS_NEG (b))
return -1;
/* now b > 0 */
else if (MPFR_UNLIKELY(i == 0))
diff --git a/mpfr.texi b/mpfr.texi
index a6eea04c1..1c978f367 100644
--- a/mpfr.texi
+++ b/mpfr.texi
@@ -1091,6 +1091,7 @@ when @var{rop} and @var{op1} are identical.
@deftypefunx int mpfr_cmp_ui (mpfr_t @var{op1}, unsigned long int @var{op2})
@deftypefunx int mpfr_cmp_si (mpfr_t @var{op1}, signed long int @var{op2})
@deftypefunx int mpfr_cmp_d (mpfr_t @var{op1}, double @var{op2})
+@deftypefunx int mpfr_cmp_ld (mpfr_t @var{op1}, long double @var{op2})
@deftypefunx int mpfr_cmp_z (mpfr_t @var{op1}, mpz_t @var{op2})
@deftypefunx int mpfr_cmp_q (mpfr_t @var{op1}, mpq_t @var{op2})
@deftypefunx int mpfr_cmp_f (mpfr_t @var{op1}, mpf_t @var{op2})
@@ -1099,7 +1100,8 @@ Compare @var{op1} and @var{op2}. Return a positive value if @math{@var{op1} >
@math{@var{op1} < @var{op2}}.
Both @var{op1} and @var{op2} are considered to their full own precision,
which may differ.
-If one of the operands is NaN (Not-a-Number), the behavior is undefined.
+If one of the operands is NaN (Not-a-Number), it returns 0 and set
+the erange flag.
@end deftypefun
@deftypefun int mpfr_cmp_ui_2exp (mpfr_t @var{op1}, unsigned long int @var{op2}, mp_exp_t @var{e})
@@ -1112,7 +1114,8 @@ the power @var{e}}. Similar as above.
Compare @math{|@var{op1}|} and @math{|@var{op2}|}. Return a positive value if
@math{|@var{op1}| > |@var{op2}|}, zero if @math{|@var{op1}| = |@var{op2}|}, and
a negative value if @math{|@var{op1}| < |@var{op2}|}.
-If one of the operands is NaN (Not-a-Number), the behavior is undefined.
+If one of the operands is NaN (Not-a-Number), it returns 0 and set
+the erange flag.
@end deftypefun
@deftypefun int mpfr_nan_p (mpfr_t @var{op})
diff --git a/tests/tcmp.c b/tests/tcmp.c
index 75bfa7020..f40e9dbe1 100644
--- a/tests/tcmp.c
+++ b/tests/tcmp.c
@@ -186,7 +186,31 @@ main (void)
}
}
}
-
+
+ /* Check for NAN */
+ mpfr_set_nan (xx);
+ mpfr_clear_erangeflag ();
+ c = mpfr_cmp (xx, yy);
+ if (c != 0 || !mpfr_erangeflag_p () )
+ {
+ printf ("NAN error (1)\n");
+ exit (1);
+ }
+ mpfr_clear_erangeflag ();
+ c = mpfr_cmp (yy, xx);
+ if (c != 0 || !mpfr_erangeflag_p () )
+ {
+ printf ("NAN error (2)\n");
+ exit (1);
+ }
+ mpfr_clear_erangeflag ();
+ c = mpfr_cmp (xx, xx);
+ if (c != 0 || !mpfr_erangeflag_p () )
+ {
+ printf ("NAN error (3)\n");
+ exit (1);
+ }
+
mpfr_clear (xx);
mpfr_clear (yy);
diff --git a/tests/tcmp_d.c b/tests/tcmp_d.c
index 8d9f25e14..270aa75c3 100644
--- a/tests/tcmp_d.c
+++ b/tests/tcmp_d.c
@@ -28,6 +28,7 @@ int
main (void)
{
mpfr_t x;
+ int c;
tests_start_mpfr ();
@@ -66,6 +67,23 @@ main (void)
exit (1);
}
+ /* Check NAN */
+ mpfr_clear_erangeflag ();
+ c = mpfr_cmp_d (x, DBL_NAN);
+ if (c != 0 || !mpfr_erangeflag_p ())
+ {
+ printf ("ERROR for NAN (1)\n");
+ exit (1);
+ }
+ mpfr_set_nan (x);
+ mpfr_clear_erangeflag ();
+ c = mpfr_cmp_d (x, 2.0);
+ if (c != 0 || !mpfr_erangeflag_p ())
+ {
+ printf ("ERROR for NAN (2)\n");
+ exit (1);
+ }
+
mpfr_clear(x);
tests_end_mpfr ();
diff --git a/tests/tcmp_ld.c b/tests/tcmp_ld.c
index 51810d6ba..23ca045dc 100644
--- a/tests/tcmp_ld.c
+++ b/tests/tcmp_ld.c
@@ -27,6 +27,7 @@ int
main (void)
{
mpfr_t x;
+ int c;
tests_start_mpfr ();
@@ -65,6 +66,24 @@ main (void)
exit (1);
}
+ /* Check NAN */
+ mpfr_clear_erangeflag ();
+ c = mpfr_cmp_ld (x, DBL_NAN);
+ if (c != 0 || !mpfr_erangeflag_p ())
+ {
+ printf ("ERROR for NAN (1)\n");
+ exit (1);
+ }
+ mpfr_set_nan (x);
+ mpfr_clear_erangeflag ();
+ c = mpfr_cmp_ld (x, 2.0);
+ if (c != 0 || !mpfr_erangeflag_p ())
+ {
+ printf ("ERROR for NAN (2)\n");
+ exit (1);
+ }
+
+
mpfr_clear(x);
tests_end_mpfr ();
diff --git a/tests/tcmp_ui.c b/tests/tcmp_ui.c
index a5c83518d..819bf4649 100644
--- a/tests/tcmp_ui.c
+++ b/tests/tcmp_ui.c
@@ -27,7 +27,10 @@ MA 02111-1307, USA. */
int
main (void)
{
- mpfr_t x; unsigned long i; long s;
+ mpfr_t x;
+ unsigned long i;
+ long s;
+ int c;
tests_start_mpfr ();
@@ -123,6 +126,23 @@ main (void)
/* now EXP(x)=BITS_PER_MP_LIMB */
MPFR_ASSERTN(mpfr_cmp_si (x, 1) > 0);
+ /* Check NAN */
+ mpfr_set_nan (x);
+ mpfr_clear_erangeflag ();
+ c = mpfr_cmp_ui (x, 12);
+ if (c != 0 || !mpfr_erangeflag_p () )
+ {
+ printf ("NAN error (1)\n");
+ exit (1);
+ }
+ mpfr_clear_erangeflag ();
+ c = mpfr_cmp_si (x, -12);
+ if (c != 0 || !mpfr_erangeflag_p () )
+ {
+ printf ("NAN error (2)\n");
+ exit (1);
+ }
+
mpfr_clear (x);
tests_end_mpfr ();
diff --git a/tests/tcmpabs.c b/tests/tcmpabs.c
index 7c6e8b544..a0a9a9e9c 100644
--- a/tests/tcmpabs.c
+++ b/tests/tcmpabs.c
@@ -30,6 +30,7 @@ int
main (void)
{
mpfr_t xx, yy;
+ int c;
tests_start_mpfr ();
@@ -105,6 +106,30 @@ main (void)
if (mpfr_cmpabs (xx, yy) >= 0)
ERROR ("Error in mpfr_cmpabs(10.235, 2346.09234)\n");
+ /* Check for NAN */
+ mpfr_set_nan (xx);
+ mpfr_clear_erangeflag ();
+ c = mpfr_cmp (xx, yy);
+ if (c != 0 || !mpfr_erangeflag_p () )
+ {
+ printf ("NAN error (1)\n");
+ exit (1);
+ }
+ mpfr_clear_erangeflag ();
+ c = mpfr_cmp (yy, xx);
+ if (c != 0 || !mpfr_erangeflag_p () )
+ {
+ printf ("NAN error (2)\n");
+ exit (1);
+ }
+ mpfr_clear_erangeflag ();
+ c = mpfr_cmp (xx, xx);
+ if (c != 0 || !mpfr_erangeflag_p () )
+ {
+ printf ("NAN error (3)\n");
+ exit (1);
+ }
+
mpfr_clear (xx);
mpfr_clear (yy);