diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2019-08-21 08:57:50 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2019-08-21 08:57:50 +0000 |
commit | 0f9ef3bea0bda632c6dff473ca762c41a974fe22 (patch) | |
tree | 3a61018b4caa0d2a105f13f79f213cc1fb411fb7 /tests | |
parent | 7162a04de5739355ad457fd2cfa06605209e403a (diff) | |
download | mpfr-0f9ef3bea0bda632c6dff473ca762c41a974fe22.tar.gz |
[tests/tget_set_d128.c] Updated a test with a non-canonical encoding:
* More meaningful name ("noncanonical" instead of "coverage").
* Output details in case of failure.
* Avoid GCC bug 91226: wrong propagation of non-canonical _Decimal64
and _Decimal128 constant (BID only).
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@13569 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'tests')
-rw-r--r-- | tests/tget_set_d128.c | 44 |
1 files changed, 39 insertions, 5 deletions
diff --git a/tests/tget_set_d128.c b/tests/tget_set_d128.c index 8b51c1e73..36132483b 100644 --- a/tests/tget_set_d128.c +++ b/tests/tget_set_d128.c @@ -449,37 +449,71 @@ check_misc (void) } static void -coverage (void) +noncanonical (void) { /* The code below assumes BID. */ #if HAVE_DECIMAL128_IEEE && !defined(DPD_FORMAT) union ieee_decimal128 x; + MPFR_ASSERTN (sizeof (x) == 16); /* produce a non-canonical decimal128 with Gh >= 24 */ x.d128 = 1; /* if BID, we have sig=0, comb=49408, t0=t1=t2=0, t3=1 */ if (x.s.sig == 0 && x.s.comb == 49408 && x.s.t0 == 0 && x.s.t1 == 0 && x.s.t2 == 0 && x.s.t3 == 1) { + /* The volatile below avoids _Decimal128 constant propagation, which is + buggy for non-canonical encoding in various GCC versions on the x86 + and x86_64 targets: failure in the second test below ("Error 2") + with gcc (Debian 20190820-1) 10.0.0 20190820 (experimental) + [trunk revision 274744]. The MPFR test was not failing with previous + GCC versions, not even with gcc (Debian 20190719-1) 10.0.0 20190718 + (experimental) [trunk revision 273586] (contrary to the similar test + in tget_set_d64.c). More information at: + https://gcc.gnu.org/bugzilla/show_bug.cgi?id=91226 + */ + volatile _Decimal128 d = 9999999999999999999999999999999999.0dl; mpfr_t y; + x.s.comb = 98560; /* force Gh >= 24 thus a non-canonical number (significand >= 2^113 > 20^34-1) */ mpfr_init2 (y, 113); mpfr_set_decimal128 (y, x.d128, MPFR_RNDN); - MPFR_ASSERTN(mpfr_zero_p (y) && mpfr_signbit (y) == 0); + if (MPFR_NOTZERO (y) || MPFR_IS_NEG (y)) + { + int i; + printf ("Error 1 in noncanonical on"); + for (i = 0; i < 16; i++) + printf (" %02X", ((unsigned char *)&x)[i]); + printf ("\nExpected +0, got:\n"); + mpfr_dump (y); + exit (1); + } /* now construct a case Gh < 24, but where the significand exceeds 10^34-1 */ - x.d128 = 9999999999999999999999999999999999.0dl; + x.d128 = d; /* should give sig=0, comb=49415, t0=11529, t1=3199043520, t2=932023907, t3=4294967295 */ x.s.t3 ++; /* should give 0 */ x.s.t2 += (x.s.t3 == 0); /* now the significand is 10^34 */ mpfr_set_decimal128 (y, x.d128, MPFR_RNDN); - MPFR_ASSERTN(mpfr_zero_p (y) && mpfr_signbit (y) == 0); + if (MPFR_NOTZERO (y) || MPFR_IS_NEG (y)) + { + int i; + printf ("Error 2 in noncanonical on"); + for (i = 0; i < 16; i++) + printf (" %02X", ((unsigned char *)&x)[i]); + printf ("\nExpected +0, got:\n"); + mpfr_dump (y); + exit (1); + } + mpfr_clear (y); } + else + printf ("Warning! Unexpected value of x in noncanonical.\n"); #endif } @@ -543,7 +577,7 @@ main (int argc, char *argv[]) #if !defined(MPFR_ERRDIVZERO) check_misc (); #endif - coverage (); + noncanonical (); tests_end_mpfr (); return 0; |