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