summaryrefslogtreecommitdiff
path: root/tools/mpcheck/mpcheck-float.c
diff options
context:
space:
mode:
Diffstat (limited to 'tools/mpcheck/mpcheck-float.c')
-rw-r--r--tools/mpcheck/mpcheck-float.c247
1 files changed, 247 insertions, 0 deletions
diff --git a/tools/mpcheck/mpcheck-float.c b/tools/mpcheck/mpcheck-float.c
new file mode 100644
index 0000000..9e4bdea
--- /dev/null
+++ b/tools/mpcheck/mpcheck-float.c
@@ -0,0 +1,247 @@
+/* mpcheck-float -- compare mpc functions against "float 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <complex.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <assert.h>
+#include "mpc.h"
+#ifdef __GNUC__
+#include <gnu/libc-version.h>
+#endif
+
+#define PRECISION 24
+#define EMAX 128
+#define TYPE float
+#define SUFFIX f
+
+#define mpfr_set_type mpfr_set_flt
+
+static TYPE complex
+mpc_get_type (mpc_t x, mpc_rnd_t rnd)
+{
+ /* there is no mpc_get_fltc function */
+ return (TYPE complex) mpc_get_dc (x, rnd);
+}
+
+static int
+mpc_set_type (mpc_t x, TYPE complex y, mpc_rnd_t rnd)
+{
+ /* there is no mpc_set_fltc function */
+ return mpc_set_dc (x, (double complex) y, rnd);
+}
+
+gmp_randstate_t state;
+mpz_t expz; /* global variable used in mpcheck_random */
+unsigned long seed = 0;
+int verbose = 0;
+mpfr_exp_t emin, emax;
+
+#include "mpcheck-common.c"
+
+#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 'float' */
+ 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 if (strcmp (argv[1], "-check") == 0)
+ {
+ recheck = 1;
+ argc --;
+ argv ++;
+ }
+ else
+ {
+ fprintf (stderr, "Unknown option %s\n", argv[1]);
+ exit (1);
+ }
+ }
+
+ /* set exponent range */
+ emin = -EMAX - PRECISION + 4; /* should be -148 */
+ emax = EMAX;
+ mpfr_set_emin (emin);
+ mpfr_set_emax (emax);
+
+ gmp_randinit_default (state);
+ mpz_init (expz);
+
+#ifdef __GNUC__
+ printf ("GNU libc version: %s\n", gnu_get_libc_version ());
+ printf ("GNU libc release: %s\n", gnu_get_libc_release ());
+#endif
+
+ if (seed == 0)
+ seed = getpid ();
+ 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);
+ mpz_clear (expz);
+
+ report_maximal_errors ();
+
+ return 0;
+}