Home | History | Annotate | Line # | Download | only in mpcheck
      1 /* mpcheck-float -- compare mpc functions against "float complex"
      2                      from the GNU libc implementation
      3 
      4 Copyright (C) 2020 INRIA
      5 
      6 This file is part of GNU MPC.
      7 
      8 GNU MPC is free software; you can redistribute it and/or modify it under
      9 the terms of the GNU Lesser General Public License as published by the
     10 Free Software Foundation; either version 3 of the License, or (at your
     11 option) any later version.
     12 
     13 GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
     14 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
     15 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
     16 more details.
     17 
     18 You should have received a copy of the GNU Lesser General Public License
     19 along with this program. If not, see http://www.gnu.org/licenses/ .
     20 */
     21 
     22 /* the GNU libc provides the following functions (as of 2.31),
     23    with 'f' suffix for the float/binary32 version, with no suffix
     24    for the double/binary64 version, with 'l' suffix for the long double
     25    version, and with 'f128' suffix for the __float128 version:
     26 
     27    cabs     casinh    cexp      csinh
     28    cacos    catan     clog      csqrt
     29    cacosh   catanh    clog10    ctan
     30    carg     ccos      cpow      ctanh
     31    casin    ccosh     csin
     32 */
     33 
     34 #define _GNU_SOURCE /* for clog10 */
     35 #include <stdio.h>
     36 #include <stdlib.h>
     37 #include <string.h>
     38 #include <complex.h>
     39 #include <sys/types.h>
     40 #include <unistd.h>
     41 #include <assert.h>
     42 #include "mpc.h"
     43 #ifdef __GNUC__
     44 #include <gnu/libc-version.h>
     45 #endif
     46 
     47 #define PRECISION 24
     48 #define EMAX 128
     49 #define TYPE float
     50 #define SUFFIX f
     51 
     52 #define mpfr_set_type mpfr_set_flt
     53 
     54 static TYPE complex
     55 mpc_get_type (mpc_t x, mpc_rnd_t rnd)
     56 {
     57   /* there is no mpc_get_fltc function */
     58   return (TYPE complex) mpc_get_dc (x, rnd);
     59 }
     60 
     61 static int
     62 mpc_set_type (mpc_t x, TYPE complex y, mpc_rnd_t rnd)
     63 {
     64   /* there is no mpc_set_fltc function */
     65   return mpc_set_dc (x, (double complex) y, rnd);
     66 }
     67 
     68 gmp_randstate_t state;
     69 mpz_t expz; /* global variable used in mpcheck_random */
     70 unsigned long seed = 0;
     71 int verbose = 0;
     72 mpfr_exp_t emin, emax;
     73 
     74 #include "mpcheck-common.c"
     75 
     76 #define FOO add
     77 #define CFOO(x,y) (x+y)
     78 #include "mpcheck-template3.c"
     79 
     80 #define FOO sub
     81 #define CFOO(x,y) (x-y)
     82 #include "mpcheck-template3.c"
     83 
     84 #define FOO mul
     85 #define CFOO(x,y) (x*y)
     86 #include "mpcheck-template3.c"
     87 
     88 #define FOO div
     89 #define CFOO(x,y) (x/y)
     90 #include "mpcheck-template3.c"
     91 
     92 #define FOO pow
     93 #include "mpcheck-template3.c"
     94 
     95 #define FOO abs
     96 #include "mpcheck-template2.c"
     97 
     98 #define FOO arg
     99 #include "mpcheck-template2.c"
    100 
    101 #define FOO sqrt
    102 #include "mpcheck-template1.c"
    103 
    104 #define FOO acos
    105 #include "mpcheck-template1.c"
    106 
    107 #define FOO acosh
    108 #include "mpcheck-template1.c"
    109 
    110 #define FOO asin
    111 #include "mpcheck-template1.c"
    112 
    113 #define FOO asinh
    114 #include "mpcheck-template1.c"
    115 
    116 #define FOO atan
    117 #include "mpcheck-template1.c"
    118 
    119 #define FOO atanh
    120 #include "mpcheck-template1.c"
    121 
    122 #define FOO cos
    123 #include "mpcheck-template1.c"
    124 
    125 #define FOO cosh
    126 #include "mpcheck-template1.c"
    127 
    128 #define FOO exp
    129 #include "mpcheck-template1.c"
    130 
    131 #define FOO log
    132 #include "mpcheck-template1.c"
    133 
    134 #define FOO log10
    135 #include "mpcheck-template1.c"
    136 
    137 #define FOO sin
    138 #include "mpcheck-template1.c"
    139 
    140 #define FOO sinh
    141 #include "mpcheck-template1.c"
    142 
    143 #define FOO tan
    144 #include "mpcheck-template1.c"
    145 
    146 #define FOO tanh
    147 #include "mpcheck-template1.c"
    148 
    149 int
    150 main (int argc, char *argv[])
    151 {
    152   mpfr_prec_t p = PRECISION; /* precision of 'float' */
    153   unsigned long n = 1000000; /* default number of random tests per function */
    154 
    155   while (argc >= 2 && argv[1][0] == '-')
    156     {
    157       if (argc >= 3 && strcmp (argv[1], "-p") == 0)
    158         {
    159           p = atoi (argv[2]);
    160           argc -= 2;
    161           argv += 2;
    162         }
    163       else if (argc >= 3 && strcmp (argv[1], "-seed") == 0)
    164         {
    165           seed = atoi (argv[2]);
    166           argc -= 2;
    167           argv += 2;
    168         }
    169       else if (argc >= 3 && strcmp (argv[1], "-num") == 0)
    170         {
    171           n = atoi (argv[2]);
    172           argc -= 2;
    173           argv += 2;
    174         }
    175       else if (strcmp (argv[1], "-v") == 0)
    176         {
    177           verbose ++;
    178           argc --;
    179           argv ++;
    180         }
    181       else if (strcmp (argv[1], "-check") == 0)
    182         {
    183           recheck = 1;
    184           argc --;
    185           argv ++;
    186         }
    187       else
    188         {
    189           fprintf (stderr, "Unknown option %s\n", argv[1]);
    190           exit (1);
    191         }
    192     }
    193 
    194   /* set exponent range */
    195   emin = -EMAX - PRECISION + 4; /* should be -148 */
    196   emax = EMAX;
    197   mpfr_set_emin (emin);
    198   mpfr_set_emax (emax);
    199 
    200   gmp_randinit_default (state);
    201   mpz_init (expz);
    202 
    203   printf ("Using GMP %s, MPFR %s\n", gmp_version, mpfr_get_version ());
    204 
    205 #ifdef __GNUC__
    206   printf ("GNU libc version: %s\n", gnu_get_libc_version ());
    207   printf ("GNU libc release: %s\n", gnu_get_libc_release ());
    208 #endif
    209 
    210   if (seed == 0)
    211     seed = getpid ();
    212   printf ("Using random seed %lu\n", seed);
    213 
    214   /* (complex,complex) -> complex */
    215   test_add (p, n);
    216   test_sub (p, n);
    217   test_mul (p, n);
    218   test_div (p, n);
    219   test_pow (p, n);
    220 
    221   /* complex -> real */
    222   test_abs (p, n);
    223   test_arg (p, n);
    224 
    225   /* complex -> complex */
    226   test_sqrt (p, n);
    227   test_acos (p, n);
    228   test_acosh (p, n);
    229   test_asin (p, n);
    230   test_asinh (p, n);
    231   test_atan (p, n);
    232   test_atanh (p, n);
    233   test_cos (p, n);
    234   test_cosh (p, n);
    235   test_exp (p, n);
    236   test_log (p, n);
    237   test_log10 (p, n);
    238   test_sin (p, n);
    239   test_sinh (p, n);
    240   test_tan (p, n);
    241   test_tanh (p, n);
    242 
    243   gmp_randclear (state);
    244   mpz_clear (expz);
    245 
    246   report_maximal_errors ();
    247 
    248   return 0;
    249 }
    250