Eric Blake <ebb9 <at> byu.net> writes: > > Here's one idea. Since it fixes the mingw cross-compilation failure of test- > isnanl-nolibm, I'm installing it; if we come up with something better or more > efficient in the future, we can alter the test then. > > The idea behind this patch is that = doesn't alter the bit pattern of an > invalid representation that sneaks past the == check, but +0 will result in a > normalized bit pattern, so that the memcmp can then filter out pseudo- > denormals. For all valid bit patterns, the == already filtered out NaN, so > adding +0.0 is a no-op to the bit pattern. Here's a snippet of my gdb session > on mingw that shows this point (where sizeof(long double) is 12):
That fix was insufficient, since it failed on isnan(-0.0L) (-0.0 + 0.0 is +0.0, not -0.0, not to mention that the padding bits in m1 and m2 were uninitialized and could differ). Since the failure on -0.0L wasn't caught until the test- vasprintf-posix test, I'm augmenting test-isnan* to actually try this case. From: Eric Blake <[EMAIL PROTECTED]> Date: Tue, 11 Dec 2007 14:00:26 -0700 Subject: [PATCH] Fix bug with -0.0L in previous patch. * lib/isnan.c (rpl_isnanl): Make robust to -0.0L and pad bits. * tests/test-isnan.c (main): Also test on zeroes. * tests/test-isnanf.c (main): Likewise. * tests/test-isnanl.h (main): Likewise. Signed-off-by: Eric Blake <[EMAIL PROTECTED]> --- ChangeLog | 6 ++++++ lib/isnan.c | 4 +++- tests/test-isnan.c | 2 ++ tests/test-isnanf.c | 2 ++ tests/test-isnanl.h | 2 ++ 5 files changed, 15 insertions(+), 1 deletions(-) diff --git a/ChangeLog b/ChangeLog index 127f9a5..a954c4c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,11 @@ 2007-12-11 Eric Blake <[EMAIL PROTECTED]> + Fix bug with -0.0L in previous patch. + * lib/isnan.c (rpl_isnanl): Make robust to -0.0L and pad bits. + * tests/test-isnan.c (main): Also test on zeroes. + * tests/test-isnanf.c (main): Likewise. + * tests/test-isnanl.h (main): Likewise. + Detect pseudo-denormals on x86 even when cross-compiling. * lib/isnan.c (rpl_isnanl) [!KNOWN_EXPBIT0_LOCATION && USE_LONG_DOUBLE && x86]: Add one more check to filter out diff --git a/lib/isnan.c b/lib/isnan.c index 182a7bd..04bf7f0 100644 --- a/lib/isnan.c +++ b/lib/isnan.c @@ -146,8 +146,10 @@ FUNC (DOUBLE x) memory_double m1; memory_double m2; + memset (&m1.value, 0, SIZE); + memset (&m2.value, 0, SIZE); m1.value = x; - m2.value = x + 0; + m2.value = x + (x ? 0.0L : -0.0L); if (memcmp (&m1.value, &m2.value, SIZE) != 0) return 1; # endif diff --git a/tests/test-isnan.c b/tests/test-isnan.c index 717ad7a..3541af4 100644 --- a/tests/test-isnan.c +++ b/tests/test-isnan.c @@ -57,6 +57,8 @@ main () ASSERT (!isnan (-2.718)); ASSERT (!isnan (-2.718e30)); ASSERT (!isnan (-2.718e-30)); + ASSERT (!isnan (0.0)); + ASSERT (!isnan (-0.0)); /* Infinite values. */ ASSERT (!isnan (1.0 / 0.0)); ASSERT (!isnan (-1.0 / 0.0)); diff --git a/tests/test-isnanf.c b/tests/test-isnanf.c index 898e6ed..c433089 100644 --- a/tests/test-isnanf.c +++ b/tests/test-isnanf.c @@ -57,6 +57,8 @@ main () ASSERT (!isnanf (-2.718f)); ASSERT (!isnanf (-2.718e30f)); ASSERT (!isnanf (-2.718e-30f)); + ASSERT (!isnanf (0.0f)); + ASSERT (!isnanf (-0.0f)); /* Infinite values. */ ASSERT (!isnanf (1.0f / 0.0f)); ASSERT (!isnanf (-1.0f / 0.0f)); diff --git a/tests/test-isnanl.h b/tests/test-isnanl.h index 5885457..657948c 100644 --- a/tests/test-isnanl.h +++ b/tests/test-isnanl.h @@ -47,6 +47,8 @@ main () ASSERT (!isnanl (-2.718L)); ASSERT (!isnanl (-2.718e30L)); ASSERT (!isnanl (-2.718e-30L)); + ASSERT (!isnanl (0.0L)); + ASSERT (!isnanl (-0.0L)); /* Infinite values. */ ASSERT (!isnanl (1.0L / 0.0L)); ASSERT (!isnanl (-1.0L / 0.0L)); -- 1.5.3.5