diff options
author | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2016-01-15 09:50:55 +0000 |
---|---|---|
committer | vlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4> | 2016-01-15 09:50:55 +0000 |
commit | a2e0e00bf35bccd1df6cda2d02ad648564f84d98 (patch) | |
tree | 6f524d01939327d54231bd0c2f1d94a5a06d3539 /tests/tlog_ui.c | |
parent | 2b56d81f52a8587386e444e52faf2d000215bc1f (diff) | |
download | mpfr-a2e0e00bf35bccd1df6cda2d02ad648564f84d98.tar.gz |
[tests/tlog_ui.c]
* In the loop, do not test n = 0 and n = 1, because mpfr_can_round
always fails for these values, so that the test is pointless.
* Check that mpfr_can_round no longer fails (this is possible as
we are not doing random tests, i.e. the tested values are known);
the additional precision for y had to be increased.
* Also test large values of n (ULONG_MAX down to ULONG_MAX-19). When
GCC's run-time sanitizer -fsanitize=undefined -fno-sanitize-recover
is used, it signals an error for large values of n.
* The reference values y are obtained with mpfr_log instead of
mpfr_log_ui: indeed we need a different implementation from the
tested function, otherwise only the rounding is tested! Without
GCC's run-time sanitizer, this shows that mpfr_log_ui is buggy
for large values of n.
git-svn-id: svn://scm.gforge.inria.fr/svn/mpfr/trunk@9810 280ebfd0-de03-0410-8827-d642c229c3f4
Diffstat (limited to 'tests/tlog_ui.c')
-rw-r--r-- | tests/tlog_ui.c | 34 |
1 files changed, 21 insertions, 13 deletions
diff --git a/tests/tlog_ui.c b/tests/tlog_ui.c index 0a7746b14..7e0e8dcc3 100644 --- a/tests/tlog_ui.c +++ b/tests/tlog_ui.c @@ -29,8 +29,8 @@ main (int argc, char *argv[]) { unsigned int prec, yprec; int rnd; - mpfr_t x, y, z, t; - unsigned long n; + mpfr_t x, y, z, t, v; + unsigned long m, n; int inex; mpfr_exp_t emin, emax; int i; @@ -40,10 +40,8 @@ main (int argc, char *argv[]) emin = mpfr_get_emin (); emax = mpfr_get_emax (); - mpfr_init (x); - mpfr_init (y); - mpfr_init (z); - mpfr_init (t); + mpfr_inits2 (53, x, y, z, t, (mpfr_ptr) 0); + mpfr_init2 (v, sizeof (unsigned long) * CHAR_BIT); if (argc >= 3) /* tlog_ui n prec [rnd] */ { @@ -98,13 +96,18 @@ main (int argc, char *argv[]) mpfr_set_prec (x, prec); mpfr_set_prec (z, prec); mpfr_set_prec (t, prec); - yprec = prec + 10; + yprec = prec + 20; mpfr_set_prec (y, yprec); - for (n = 0; n < 50; n++) + for (m = 2; m < 70; m++) RND_LOOP (rnd) { - TEST_FUNCTION (y, n, MPFR_RNDN); + /* Start with n = 2 to 49 (mpfr_can_round would fail for n < 2), + then ULONG_MAX down to ULONG_MAX-19. */ + n = m < 50 ? m : ULONG_MAX - (m - 50); + inex = mpfr_set_ui (v, n, MPFR_RNDN); + MPFR_ASSERTN (inex == 0); + mpfr_log (y, v, MPFR_RNDN); if (mpfr_can_round (y, yprec, MPFR_RNDN, MPFR_RNDZ, prec + (rnd == MPFR_RNDN))) { @@ -143,14 +146,19 @@ main (int argc, char *argv[]) } } } + else + { + /* We are not doing random tests. The precision increase + must have be chosen so that this case never occurs. */ + printf ("mpfr_can_round failed for n = %lu, prec = %u, %s\n", + n, prec, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); + exit (1); + } } } clear_and_exit: - mpfr_clear (x); - mpfr_clear (y); - mpfr_clear (z); - mpfr_clear (t); + mpfr_clears (x, y, z, t, v, (mpfr_ptr) 0); tests_end_mpfr (); return 0; |