summaryrefslogtreecommitdiff
path: root/tests/tlog_ui.c
diff options
context:
space:
mode:
authorvlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2016-01-15 09:50:55 +0000
committervlefevre <vlefevre@280ebfd0-de03-0410-8827-d642c229c3f4>2016-01-15 09:50:55 +0000
commita2e0e00bf35bccd1df6cda2d02ad648564f84d98 (patch)
tree6f524d01939327d54231bd0c2f1d94a5a06d3539 /tests/tlog_ui.c
parent2b56d81f52a8587386e444e52faf2d000215bc1f (diff)
downloadmpfr-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.c34
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;