Home | History | Annotate | Line # | Download | only in tests
      1 /* exceptions -- test file for exceptions
      2 
      3 Copyright (C) 2015, 2022 INRIA
      4 
      5 This file is part of GNU MPC.
      6 
      7 GNU MPC is free software; you can redistribute it and/or modify it under
      8 the terms of the GNU Lesser General Public License as published by the
      9 Free Software Foundation; either version 3 of the License, or (at your
     10 option) any later version.
     11 
     12 GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY
     13 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
     14 FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for
     15 more details.
     16 
     17 You should have received a copy of the GNU Lesser General Public License
     18 along with this program. If not, see http://www.gnu.org/licenses/ .
     19 */
     20 
     21 #include "mpc-tests.h"
     22 
     23 /* Return non-zero if 'rnd' rounds towards zero, for a number of sign 'sgn' */
     24 #define MPC_IS_LIKE_RNDZ(rnd, sgn) \
     25   ((rnd==MPFR_RNDZ) || (sgn<0 && rnd==MPFR_RNDU) || (sgn>0 && rnd==MPFR_RNDD))
     26 
     27 #define MPFR_SGN(x) (mpfr_signbit (x) ? -1 : 1)
     28 
     29 static void
     30 foo (int f(mpc_ptr, mpc_srcptr, mpc_rnd_t), const char *s)
     31 {
     32   mpc_t z, t;
     33   mpfr_rnd_t rnd_re, rnd_im;
     34   mpc_rnd_t rnd;
     35 #define N 5
     36   mpfr_exp_t exy[N][2] = {{200, 800}, {800, 200}, {-50, 50}, {-10, 1000},
     37                           {0, 1000}};
     38   int n, inex, inex_re, inex_im, sgn;
     39 
     40   mpc_init2 (z, MPFR_PREC_MIN);
     41   mpc_init2 (t, MPFR_PREC_MIN);
     42   for (n = 0; n < N; n++)
     43     for (sgn = 0; sgn < 4; sgn++)
     44     {
     45       if (exy[n][0])
     46         mpfr_set_ui_2exp (mpc_realref (z), 1, exy[n][0], MPFR_RNDN);
     47       else
     48         mpfr_set_ui (mpc_realref (z), 0, MPFR_RNDN);
     49       if (sgn & 1)
     50         mpfr_neg (mpc_realref (z), mpc_realref (z), MPFR_RNDN);
     51       if (exy[n][1])
     52         mpfr_set_ui_2exp (mpc_imagref (z), 1, exy[n][1], MPFR_RNDN);
     53       else
     54         mpfr_set_ui (mpc_imagref (z), 0, MPFR_RNDN);
     55       if (sgn & 2)
     56         mpfr_neg (mpc_imagref (z), mpc_imagref (z), MPFR_RNDN);
     57 
     58       inex = f (t, z, MPC_RNDZZ);
     59       inex_re = MPC_INEX_RE(inex);
     60       inex_im = MPC_INEX_IM(inex);
     61 
     62       if (inex_re != 0 && mpfr_inf_p (mpc_realref (t)))
     63         {
     64           fprintf (stderr, "Error, wrong real part with rounding towards zero\n");
     65           fprintf (stderr, "f = %s\n", s);
     66           fprintf (stderr, "z=");
     67           mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
     68           fprintf (stderr, "\nt=");
     69           mpc_out_str (stderr, 2, 0, t, MPC_RNDNN);
     70           fprintf (stderr, "\n");
     71           exit (1);
     72         }
     73 
     74       if (inex_im != 0 && mpfr_inf_p (mpc_imagref (t)))
     75         {
     76           fprintf (stderr, "Error, wrong imag part with rounding towards zero\n");
     77           fprintf (stderr, "f = %s\n", s);
     78           fprintf (stderr, "z=");
     79           mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
     80           fprintf (stderr, "\nt=");
     81           mpc_out_str (stderr, 2, 0, t, MPC_RNDNN);
     82           fprintf (stderr, "\n");
     83           exit (1);
     84         }
     85 
     86       rnd_re = mpfr_signbit (mpc_realref (t)) == 0 ? MPFR_RNDU : MPFR_RNDD;
     87       rnd_im = mpfr_signbit (mpc_imagref (t)) == 0 ? MPFR_RNDU : MPFR_RNDD;
     88       rnd = MPC_RND(rnd_re,rnd_im); /* round away */
     89 
     90       inex = f (t, z, rnd);
     91       inex_re = MPC_INEX_RE(inex);
     92       inex_im = MPC_INEX_IM(inex);
     93 
     94       if (inex_re != 0 && mpfr_zero_p (mpc_realref (t)))
     95         {
     96           fprintf (stderr, "Error, wrong real part with rounding away from zero\n");
     97           fprintf (stderr, "f = %s\n", s);
     98           fprintf (stderr, "z=");
     99           mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
    100           fprintf (stderr, "\nt=");
    101           mpc_out_str (stderr, 2, 0, t, MPC_RNDNN);
    102           fprintf (stderr, "\n");
    103           fprintf (stderr, "rnd=%s\n", mpfr_print_rnd_mode (rnd_re));
    104           exit (1);
    105         }
    106 
    107       if (inex_im != 0 && mpfr_zero_p (mpc_imagref (t)))
    108         {
    109           fprintf (stderr, "Error, wrong imag part with rounding away from zero\n");
    110           fprintf (stderr, "f = %s\n", s);
    111           fprintf (stderr, "z=");
    112           mpc_out_str (stderr, 2, 0, z, MPC_RNDNN);
    113           fprintf (stderr, "\nt=");
    114           mpc_out_str (stderr, 2, 0, t, MPC_RNDNN);
    115           fprintf (stderr, "\n");
    116           fprintf (stderr, "rnd=%s\n", mpfr_print_rnd_mode (rnd_im));
    117           exit (1);
    118         }
    119     }
    120 
    121   mpc_clear (z);
    122   mpc_clear (t);
    123 }
    124 
    125 int
    126 main (void)
    127 {
    128   test_start ();
    129 
    130   foo (mpc_sqr, "sqr");
    131   foo (mpc_conj, "conj");
    132   foo (mpc_neg, "neg");
    133   foo (mpc_sqrt, "sqrt");
    134   foo (mpc_set, "set");
    135   foo (mpc_proj, "proj");
    136   foo (mpc_exp, "exp");
    137   foo (mpc_exp, "exp");
    138   foo (mpc_log, "log");
    139   foo (mpc_log10, "log10");
    140   foo (mpc_sin, "sin");
    141   foo (mpc_cos, "cos");
    142   foo (mpc_tan, "tan");
    143   foo (mpc_sinh, "sinh");
    144   foo (mpc_cosh, "cosh");
    145   foo (mpc_tanh, "tanh");
    146   foo (mpc_asin, "asin");
    147   foo (mpc_acos, "acos");
    148   foo (mpc_atan, "atan");
    149   foo (mpc_asinh, "asinh");
    150   foo (mpc_acosh, "acosh");
    151   foo (mpc_atanh, "atanh");
    152 
    153   test_end ();
    154 
    155   return 0;
    156 }
    157