This is the mail archive of the libstdc++@gcc.gnu.org mailing list for the libstdc++ project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

PATCH: New test for breakage from real.c rewrite on i386-unknown-freebsd


Looking at test_extrema<long double> case of
libstdc++-v3/testsuite/18_support/numeric_limits.cc on
i386-unknown-freebsd5 by setting a break point after all values are
set but before the actual tests (using the FreeBSD specialization of
same since it sets epsilon).  FYI, I was looking at it not only since
it started failing but also because I thought the rewrite might remove
the need for it.  Rather than blindly removing it, I wanted to
understand why it broke.  It broke because there was an assumption
change.  I think the change is good overall but, well, read on...

Before recent real change:

(gdb) print epsilon
$1 = 2.2204460492503130808472633361816406e-16
(gdb) print/x (long double)1
$2 = 0x082a3fff8000000000000000
(gdb) print/x (1+epsilon)
$3 = 0x082a3fff8000000000000800
(gdb) print extrema_max
$4 = 1.7976931348623157081452742373170436e+308
(gdb) print/x extrema_max
$5 = 0x000043fefffffffffffff800
(gdb) print/x limits_max
$6 = 0x000043fefffffffffffff800

Notice that (long double)1 != (1+epsilon)

After recent real change:

(gdb) print epsilon
$1 = 1.0842021724855044340074528008699417e-19
(gdb) print/x (long double)1
$2 = 0x082a3fff8000000000000000
(gdb) print/x (1+epsilon)
$3 = 0x082a3fff8000000000000000
(gdb) print extrema_max
$4 = inf
(gdb) print/x extrema_max
$5 = 0x00007ffeffffffffffffffff
(gdb) print/x limits_max
$6 = 0x00007ffeffffffffffffffff

Notice that (long double)1 == (1+epsilon)

>From the ISO-C++-14882 definition of epsilon (not the IEEE
definition), this is not correct.  I found this failure on
i386-unknown-freebsd because of the specialization installed which,
while looser overall, did detect that epsilon was being set wrong
verses port FP unit setup (?).  Also, extrema_max would appear to be
wrong for this platform now (at least as published in the system
headers which themselves might be buggy and/or as printed from gdb).

FYI, config/os/bsd/freebsd/os_defines.h had (still has, but now unused):

#define __glibcpp_long_double_bits __glibcpp_double_bits

There are at least two issues.  One, we have no explicit test looking
to see if epsilon is sane (implicitly tested on FreeBSD by luck).
(See patch below.)  Two, at the time it was written, the comment about
the FreeBSD specialization of test_extrema<long double> was indeed
true.  At one time, I thought we were matching buggy system C headers
and/or stock FP setup in C++ headers.  Something should be done about
the current breakage; but since we changed assumptions, I don't know
what.  If the new intent is to have C++ headers report true rather
than mirror C headers, I will remove the FreeBSD specialization.  That
would still leave some breakage on this port (epsilon, etc) to be
resolved.

Regards,
Loren

Applied on mainline:

	* testsuite/18_support/numeric_limits.cc (test_epsilon): New.

Index: numeric_limits.cc
===================================================================
RCS file: /cvs/gcc/gcc/libstdc++-v3/testsuite/18_support/numeric_limits.cc,v
retrieving revision 1.14
diff -c -r1.14 numeric_limits.cc
*** numeric_limits.cc	18 Sep 2002 18:06:13 -0000	1.14
--- numeric_limits.cc	19 Sep 2002 04:22:37 -0000
***************
*** 94,99 ****
--- 94,109 ----
  }
  #endif
  
+ template<typename T>
+ void test_epsilon()
+ {
+   bool test = true;
+   T epsilon = std::numeric_limits<T>::epsilon();
+   T one = 1;
+ 
+   VERIFY( one != (one + epsilon) );
+ }
+ 
  #ifdef __CHAR_UNSIGNED__
  #define char_is_signed false
  #else
***************
*** 313,318 ****
--- 323,332 ----
    test_extrema<float>();
    test_extrema<double>();
    test_extrema<long double>();
+ 
+   test_epsilon<float>();
+   test_epsilon<double>();
+   test_epsilon<long double>();
  
    test_sign();
  


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]