From ad85d001a8cbc00f3255d0d3e0a97455d1f8ed03 Mon Sep 17 00:00:00 2001 From: Paul Zimmermann Date: Wed, 5 Feb 2020 21:38:56 +0100 Subject: added mpcheck-longdouble and mpcheck-float128 --- tests/Makefile.am | 3 +- tests/mpcheck-double.c | 3 +- tests/mpcheck-float.c | 7 +- tests/mpcheck-float128.c | 249 +++++++++++++++++++++++++++++++++++++++++++++ tests/mpcheck-longdouble.c | 232 +++++++++++++++++++++++++++++++++++++++++ tests/mpcheck-template1.c | 3 +- tests/mpcheck-template2.c | 3 +- tests/mpcheck-template3.c | 2 +- 8 files changed, 494 insertions(+), 8 deletions(-) create mode 100644 tests/mpcheck-float128.c create mode 100644 tests/mpcheck-longdouble.c diff --git a/tests/Makefile.am b/tests/Makefile.am index e8b08df..37f1496 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -66,7 +66,8 @@ DATA_SETS = abs.dat acos.dat acosh.dat add.dat add_fr.dat arg.dat \ sin.dat sinh.dat \ sqr.dat sqrt.dat strtoc.dat sub.dat sub_fr.dat tan.dat tanh.dat EXTRA_DIST = data_check.tpl tgeneric.tpl $(DATA_SETS) $(DESCRIPTIONS) \ - mpcheck-double.c mpcheck-float.c \ + mpcheck-float.c mpcheck-double.c mpcheck-longdouble.c \ + mpcheck-float128.c \ mpcheck-template1.c mpcheck-template2.c mpcheck-template3.c LOG_COMPILER = $(VALGRIND) diff --git a/tests/mpcheck-double.c b/tests/mpcheck-double.c index 3631252..7b3e88e 100644 --- a/tests/mpcheck-double.c +++ b/tests/mpcheck-double.c @@ -43,6 +43,7 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #define PRECISION 53 #define EMAX 1024 #define TYPE double +#define SUFFIX #define mpc_get_type mpc_get_dc #define mpc_set_type mpc_set_dc @@ -185,7 +186,7 @@ main (int argc, char *argv[]) } /* set exponent range for 'double' */ - mpfr_set_emin (-EMAX - PRECISION + 4); + mpfr_set_emin (-EMAX - PRECISION + 4); /* should be -1073 */ mpfr_set_emax (EMAX); gmp_randinit_default (state); diff --git a/tests/mpcheck-float.c b/tests/mpcheck-float.c index 10be8d1..e056c86 100644 --- a/tests/mpcheck-float.c +++ b/tests/mpcheck-float.c @@ -1,4 +1,4 @@ -/* mpcheck-double -- compare mpc functions against "float complex" +/* mpcheck-float -- compare mpc functions against "float complex" from the GNU libc implementation Copyright (C) 2020 INRIA @@ -43,6 +43,7 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #define PRECISION 24 #define EMAX 128 #define TYPE float +#define SUFFIX f #define mpfr_set_type mpfr_set_flt @@ -196,8 +197,8 @@ main (int argc, char *argv[]) } } - /* set exponent range for 'float' */ - mpfr_set_emin (-EMAX - PRECISION + 4); + /* set exponent range */ + mpfr_set_emin (-EMAX - PRECISION + 4); /* should be -148 */ mpfr_set_emax (EMAX); gmp_randinit_default (state); diff --git a/tests/mpcheck-float128.c b/tests/mpcheck-float128.c new file mode 100644 index 0000000..43f5ddf --- /dev/null +++ b/tests/mpcheck-float128.c @@ -0,0 +1,249 @@ +/* mpcheck-float128 -- compare mpc functions against "__float128 complex" + from the GNU libc implementation + +Copyright (C) 2020 INRIA + +This file is part of GNU MPC. + +GNU MPC is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see http://www.gnu.org/licenses/ . +*/ + +/* the GNU libc provides the following functions (as of 2.31), + with 'f' suffix for the float/binary32 version, with no suffix + for the double/binary64 version, with 'l' suffix for the long double + version, and with 'f128' suffix for the __float128 version: + + cabs casinh cexp csinh + cacos catan clog csqrt + cacosh catanh clog10 ctan + carg ccos cpow ctanh + casin ccosh csin +*/ + +#define _GNU_SOURCE /* for clog10 */ +#include +#include +#include +#define MPFR_WANT_FLOAT128 +#include "mpc-tests.h" +#ifdef __GNUC__ +#include +#endif + +#define PRECISION 113 +#define EMAX 16384 +#define TYPE _Float128 +#define SUFFIX f128 + +#define mpfr_set_type mpfr_set_float128 + +static TYPE complex +mpc_get_type (mpc_t z, mpc_rnd_t rnd) +{ + TYPE x, y; + /* there is no mpc_get_float128c function */ + x = mpfr_get_float128 (mpc_realref (z), MPC_RND_RE(rnd)); + y = mpfr_get_float128 (mpc_imagref (z), MPC_RND_IM(rnd)); + return x + I * y; +} + +static int +mpc_set_type (mpc_t x, TYPE complex y, mpc_rnd_t rnd) +{ + /* there is no mpc_set_float128c function */ + mpfr_set_float128 (mpc_realref (x), crealf128 (y), MPC_RND_RE(rnd)); + mpfr_set_float128 (mpc_imagref (x), cimagf128 (y), MPC_RND_IM(rnd)); +} + +gmp_randstate_t state; +unsigned long seed = 1; +int verbose = 0; + +static unsigned long +ulp_error (mpfr_t x, mpfr_t y) +{ + mpfr_t z; + mpfr_prec_t p = mpfr_get_prec (y); + unsigned long n; + + if (mpfr_cmp (x, y) == 0) + return 0; + + mpfr_init2 (z, p); + mpfr_sub (z, x, y, MPFR_RNDN); + mpfr_abs (z, z, MPFR_RNDN); + /* divide by ulp(y) = 2^(EXP(y) - p) */ + mpfr_div_2si (z, z, mpfr_get_exp (y) - p, MPFR_RNDN); + n = mpfr_get_ui (z, MPFR_RNDZ); + mpfr_clear (z); + return n; +} + +#define FOO add +#define CFOO(x,y) (x+y) +#include "mpcheck-template3.c" + +#define FOO sub +#define CFOO(x,y) (x-y) +#include "mpcheck-template3.c" + +#define FOO mul +#define CFOO(x,y) (x*y) +#include "mpcheck-template3.c" + +#define FOO div +#define CFOO(x,y) (x/y) +#include "mpcheck-template3.c" + +#define FOO pow +#include "mpcheck-template3.c" + +#define FOO abs +#include "mpcheck-template2.c" + +#define FOO arg +#include "mpcheck-template2.c" + +#define FOO sqrt +#include "mpcheck-template1.c" + +#define FOO acos +#include "mpcheck-template1.c" + +#define FOO acosh +#include "mpcheck-template1.c" + +#define FOO asin +#include "mpcheck-template1.c" + +#define FOO asinh +#include "mpcheck-template1.c" + +#define FOO atan +#include "mpcheck-template1.c" + +#define FOO atanh +#include "mpcheck-template1.c" + +#define FOO cos +#include "mpcheck-template1.c" + +#define FOO cosh +#include "mpcheck-template1.c" + +#define FOO exp +#include "mpcheck-template1.c" + +#define FOO log +#include "mpcheck-template1.c" + +#define FOO log10 +#include "mpcheck-template1.c" + +#define FOO sin +#include "mpcheck-template1.c" + +#define FOO sinh +#include "mpcheck-template1.c" + +#define FOO tan +#include "mpcheck-template1.c" + +#define FOO tanh +#include "mpcheck-template1.c" + +int +main (int argc, char *argv[]) +{ + mpfr_prec_t p = PRECISION; /* precision of 'double' */ + unsigned long n = 1000000; /* default number of random tests per function */ + + while (argc >= 2 && argv[1][0] == '-') + { + if (argc >= 3 && strcmp (argv[1], "-p") == 0) + { + p = atoi (argv[2]); + argc -= 2; + argv += 2; + } + else if (argc >= 3 && strcmp (argv[1], "-seed") == 0) + { + seed = atoi (argv[2]); + argc -= 2; + argv += 2; + } + else if (argc >= 3 && strcmp (argv[1], "-num") == 0) + { + n = atoi (argv[2]); + argc -= 2; + argv += 2; + } + else if (strcmp (argv[1], "-v") == 0) + { + verbose ++; + argc --; + argv ++; + } + else + { + fprintf (stderr, "Unknown option %s\n", argv[1]); + exit (1); + } + } + + /* set exponent range */ + mpfr_set_emin (-EMAX - 64 + 4); /* should be -16444 like for long double */ + mpfr_set_emax (EMAX); + + gmp_randinit_default (state); + +#ifdef __GNUC__ + printf ("GNU libc version: %s\n", gnu_get_libc_version ()); + printf ("GNU libc release: %s\n", gnu_get_libc_release ()); +#endif + printf ("Using random seed %lu\n", seed); + + /* (complex,complex) -> complex */ + test_add (p, n); + test_sub (p, n); + test_mul (p, n); + test_div (p, n); + test_pow (p, n); + + /* complex -> real */ + test_abs (p, n); + test_arg (p, n); + + /* complex -> complex */ + test_sqrt (p, n); + test_acos (p, n); + test_acosh (p, n); + test_asin (p, n); + test_asinh (p, n); + test_atan (p, n); + test_atanh (p, n); + test_cos (p, n); + test_cosh (p, n); + test_exp (p, n); + test_log (p, n); + test_log10 (p, n); + test_sin (p, n); + test_sinh (p, n); + test_tan (p, n); + test_tanh (p, n); + + gmp_randclear (state); + + return 0; +} diff --git a/tests/mpcheck-longdouble.c b/tests/mpcheck-longdouble.c new file mode 100644 index 0000000..f991c2e --- /dev/null +++ b/tests/mpcheck-longdouble.c @@ -0,0 +1,232 @@ +/* mpcheck-longdouble -- compare mpc functions against "long double complex" + from the GNU libc implementation + +Copyright (C) 2020 INRIA + +This file is part of GNU MPC. + +GNU MPC is free software; you can redistribute it and/or modify it under +the terms of the GNU Lesser General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY +WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS +FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for +more details. + +You should have received a copy of the GNU Lesser General Public License +along with this program. If not, see http://www.gnu.org/licenses/ . +*/ + +/* the GNU libc provides the following functions (as of 2.31), + with 'f' suffix for the float/binary32 version, with no suffix + for the double/binary64 version, with 'l' suffix for the long double + version, and with 'f128' suffix for the __float128 version: + + cabs casinh cexp csinh + cacos catan clog csqrt + cacosh catanh clog10 ctan + carg ccos cpow ctanh + casin ccosh csin +*/ + +#define _GNU_SOURCE /* for clog10 */ +#include +#include +#include +#include "mpc-tests.h" +#ifdef __GNUC__ +#include +#endif + +#define PRECISION 64 +#define EMAX 16384 +#define TYPE long double +#define SUFFIX l + +#define mpc_get_type mpc_get_ldc +#define mpc_set_type mpc_set_ldc +#define mpfr_set_type mpfr_set_ld + +gmp_randstate_t state; +unsigned long seed = 1; +int verbose = 0; + +static unsigned long +ulp_error (mpfr_t x, mpfr_t y) +{ + mpfr_t z; + mpfr_prec_t p = mpfr_get_prec (y); + unsigned long n; + + if (mpfr_cmp (x, y) == 0) + return 0; + + mpfr_init2 (z, p); + mpfr_sub (z, x, y, MPFR_RNDN); + mpfr_abs (z, z, MPFR_RNDN); + /* divide by ulp(y) = 2^(EXP(y) - p) */ + mpfr_div_2si (z, z, mpfr_get_exp (y) - p, MPFR_RNDN); + n = mpfr_get_ui (z, MPFR_RNDZ); + mpfr_clear (z); + return n; +} + +#define FOO add +#define CFOO(x,y) (x+y) +#include "mpcheck-template3.c" + +#define FOO sub +#define CFOO(x,y) (x-y) +#include "mpcheck-template3.c" + +#define FOO mul +#define CFOO(x,y) (x*y) +#include "mpcheck-template3.c" + +#define FOO div +#define CFOO(x,y) (x/y) +#include "mpcheck-template3.c" + +#define FOO pow +#include "mpcheck-template3.c" + +#define FOO abs +#include "mpcheck-template2.c" + +#define FOO arg +#include "mpcheck-template2.c" + +#define FOO sqrt +#include "mpcheck-template1.c" + +#define FOO acos +#include "mpcheck-template1.c" + +#define FOO acosh +#include "mpcheck-template1.c" + +#define FOO asin +#include "mpcheck-template1.c" + +#define FOO asinh +#include "mpcheck-template1.c" + +#define FOO atan +#include "mpcheck-template1.c" + +#define FOO atanh +#include "mpcheck-template1.c" + +#define FOO cos +#include "mpcheck-template1.c" + +#define FOO cosh +#include "mpcheck-template1.c" + +#define FOO exp +#include "mpcheck-template1.c" + +#define FOO log +#include "mpcheck-template1.c" + +#define FOO log10 +#include "mpcheck-template1.c" + +#define FOO sin +#include "mpcheck-template1.c" + +#define FOO sinh +#include "mpcheck-template1.c" + +#define FOO tan +#include "mpcheck-template1.c" + +#define FOO tanh +#include "mpcheck-template1.c" + +int +main (int argc, char *argv[]) +{ + mpfr_prec_t p = PRECISION; /* precision of 'double' */ + unsigned long n = 1000000; /* default number of random tests per function */ + + while (argc >= 2 && argv[1][0] == '-') + { + if (argc >= 3 && strcmp (argv[1], "-p") == 0) + { + p = atoi (argv[2]); + argc -= 2; + argv += 2; + } + else if (argc >= 3 && strcmp (argv[1], "-seed") == 0) + { + seed = atoi (argv[2]); + argc -= 2; + argv += 2; + } + else if (argc >= 3 && strcmp (argv[1], "-num") == 0) + { + n = atoi (argv[2]); + argc -= 2; + argv += 2; + } + else if (strcmp (argv[1], "-v") == 0) + { + verbose ++; + argc --; + argv ++; + } + else + { + fprintf (stderr, "Unknown option %s\n", argv[1]); + exit (1); + } + } + + /* set exponent range */ + mpfr_set_emin (-EMAX - PRECISION + 4); /* should be -16444 */ + mpfr_set_emax (EMAX); + + gmp_randinit_default (state); + +#ifdef __GNUC__ + printf ("GNU libc version: %s\n", gnu_get_libc_version ()); + printf ("GNU libc release: %s\n", gnu_get_libc_release ()); +#endif + printf ("Using random seed %lu\n", seed); + + /* (complex,complex) -> complex */ + test_add (p, n); + test_sub (p, n); + test_mul (p, n); + test_div (p, n); + test_pow (p, n); + + /* complex -> real */ + test_abs (p, n); + test_arg (p, n); + + /* complex -> complex */ + test_sqrt (p, n); + test_acos (p, n); + test_acosh (p, n); + test_asin (p, n); + test_asinh (p, n); + test_atan (p, n); + test_atanh (p, n); + test_cos (p, n); + test_cosh (p, n); + test_exp (p, n); + test_log (p, n); + test_log10 (p, n); + test_sin (p, n); + test_sinh (p, n); + test_tan (p, n); + test_tanh (p, n); + + gmp_randclear (state); + + return 0; +} diff --git a/tests/mpcheck-template1.c b/tests/mpcheck-template1.c index 712f8c3..742f7d3 100644 --- a/tests/mpcheck-template1.c +++ b/tests/mpcheck-template1.c @@ -25,7 +25,7 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #define FUN CAT2(test_,FOO) #define MPC_FOO CAT2(mpc_,FOO) -#define CFOO CAT2(c,FOO) +#define CFOO CAT2(CAT2(c,FOO),SUFFIX) #define BAR TOSTRING(FOO) static void @@ -80,3 +80,4 @@ FUN (mpfr_prec_t p, unsigned long n) } #undef FOO +#undef CFOO diff --git a/tests/mpcheck-template2.c b/tests/mpcheck-template2.c index e75f25f..d3513bf 100644 --- a/tests/mpcheck-template2.c +++ b/tests/mpcheck-template2.c @@ -25,7 +25,7 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #define FUN CAT2(test_,FOO) #define MPC_FOO CAT2(mpc_,FOO) -#define CFOO CAT2(c,FOO) +#define CFOO CAT2(CAT2(c,FOO),SUFFIX) #define BAR TOSTRING(FOO) static void @@ -75,3 +75,4 @@ FUN (mpfr_prec_t p, unsigned long n) } #undef FOO +#undef CFOO diff --git a/tests/mpcheck-template3.c b/tests/mpcheck-template3.c index 821e570..b42cb92 100644 --- a/tests/mpcheck-template3.c +++ b/tests/mpcheck-template3.c @@ -26,7 +26,7 @@ along with this program. If not, see http://www.gnu.org/licenses/ . #define FUN CAT2(test_,FOO) #define MPC_FOO CAT2(mpc_,FOO) #ifndef CFOO -#define CFOO CAT2(c,FOO) +#define CFOO CAT2(CAT2(c,FOO),SUFFIX) #endif #define BAR TOSTRING(FOO) -- cgit v1.2.1