diff options
author | pelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4> | 2004-09-29 13:58:06 +0000 |
---|---|---|
committer | pelissip <pelissip@280ebfd0-de03-0410-8827-d642c229c3f4> | 2004-09-29 13:58:06 +0000 |
commit | f2af580a8d5f41bc8fdebf7209c5a2959c83efc6 (patch) | |
tree | 049b34ab0e842b44e5d327a40a5001379d86c0fd | |
parent | f70d2f99fa9a99f09e1f9f602efe5930c079cee6 (diff) | |
download | mpfr-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-- | TODO | 6 | ||||
-rw-r--r-- | cmp.c | 9 | ||||
-rw-r--r-- | cmp_abs.c | 14 | ||||
-rw-r--r-- | cmp_d.c | 12 | ||||
-rw-r--r-- | cmp_si.c | 21 | ||||
-rw-r--r-- | cmp_ui.c | 12 | ||||
-rw-r--r-- | mpfr.texi | 7 | ||||
-rw-r--r-- | tests/tcmp.c | 26 | ||||
-rw-r--r-- | tests/tcmp_d.c | 18 | ||||
-rw-r--r-- | tests/tcmp_ld.c | 19 | ||||
-rw-r--r-- | tests/tcmp_ui.c | 22 | ||||
-rw-r--r-- | tests/tcmpabs.c | 25 |
12 files changed, 153 insertions, 38 deletions
@@ -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 @@ -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; @@ -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); @@ -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; } @@ -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; @@ -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)) @@ -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); |