1 1.1 mrg /* tsqr -- test file for mpc_sqr. 2 1.1 mrg 3 1.1.1.2 mrg Copyright (C) 2002, 2005, 2008, 2010, 2011, 2012, 2013 INRIA 4 1.1 mrg 5 1.1 mrg This file is part of GNU MPC. 6 1.1 mrg 7 1.1 mrg GNU MPC is free software; you can redistribute it and/or modify it under 8 1.1 mrg the terms of the GNU Lesser General Public License as published by the 9 1.1 mrg Free Software Foundation; either version 3 of the License, or (at your 10 1.1 mrg option) any later version. 11 1.1 mrg 12 1.1 mrg GNU MPC is distributed in the hope that it will be useful, but WITHOUT ANY 13 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 14 1.1 mrg FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for 15 1.1 mrg more details. 16 1.1 mrg 17 1.1 mrg You should have received a copy of the GNU Lesser General Public License 18 1.1 mrg along with this program. If not, see http://www.gnu.org/licenses/ . 19 1.1 mrg */ 20 1.1 mrg 21 1.1 mrg #include <stdlib.h> 22 1.1 mrg #include "mpc-tests.h" 23 1.1 mrg 24 1.1 mrg static void 25 1.1 mrg cmpsqr (mpc_srcptr x, mpc_rnd_t rnd) 26 1.1 mrg /* computes the square of x with the specific function or by simple */ 27 1.1 mrg /* multiplication using the rounding mode rnd and compares the results */ 28 1.1 mrg /* and return values. */ 29 1.1 mrg /* In our current test suite, the real and imaginary parts of x have */ 30 1.1 mrg /* the same precision, and we use this precision also for the result. */ 31 1.1 mrg /* Furthermore, we check whether computing the square in the same */ 32 1.1 mrg /* place yields the same result. */ 33 1.1 mrg /* We also compute the result with four times the precision and check */ 34 1.1 mrg /* whether the rounding is correct. Error reports in this part of the */ 35 1.1 mrg /* algorithm might still be wrong, though, since there are two */ 36 1.1 mrg /* consecutive roundings. */ 37 1.1 mrg { 38 1.1 mrg mpc_t z, t, u; 39 1.1 mrg int inexact_z, inexact_t; 40 1.1 mrg 41 1.1 mrg mpc_init2 (z, MPC_MAX_PREC (x)); 42 1.1 mrg mpc_init2 (t, MPC_MAX_PREC (x)); 43 1.1 mrg mpc_init2 (u, 4 * MPC_MAX_PREC (x)); 44 1.1 mrg 45 1.1 mrg inexact_z = mpc_sqr (z, x, rnd); 46 1.1 mrg inexact_t = mpc_mul (t, x, x, rnd); 47 1.1 mrg 48 1.1 mrg if (mpc_cmp (z, t)) 49 1.1 mrg { 50 1.1 mrg fprintf (stderr, "sqr and mul differ for rnd=(%s,%s) \nx=", 51 1.1 mrg mpfr_print_rnd_mode(MPC_RND_RE(rnd)), 52 1.1 mrg mpfr_print_rnd_mode(MPC_RND_IM(rnd))); 53 1.1 mrg mpc_out_str (stderr, 2, 0, x, MPC_RNDNN); 54 1.1 mrg fprintf (stderr, "\nmpc_sqr gives "); 55 1.1 mrg mpc_out_str (stderr, 2, 0, z, MPC_RNDNN); 56 1.1 mrg fprintf (stderr, "\nmpc_mul gives "); 57 1.1 mrg mpc_out_str (stderr, 2, 0, t, MPC_RNDNN); 58 1.1 mrg fprintf (stderr, "\n"); 59 1.1 mrg exit (1); 60 1.1 mrg } 61 1.1 mrg if (inexact_z != inexact_t) 62 1.1 mrg { 63 1.1 mrg fprintf (stderr, "The return values of sqr and mul differ for rnd=(%s,%s) \nx= ", 64 1.1 mrg mpfr_print_rnd_mode(MPC_RND_RE(rnd)), 65 1.1 mrg mpfr_print_rnd_mode(MPC_RND_IM(rnd))); 66 1.1 mrg mpc_out_str (stderr, 2, 0, x, MPC_RNDNN); 67 1.1 mrg fprintf (stderr, "\nx^2="); 68 1.1 mrg mpc_out_str (stderr, 2, 0, z, MPC_RNDNN); 69 1.1 mrg fprintf (stderr, "\nmpc_sqr gives %i", inexact_z); 70 1.1 mrg fprintf (stderr, "\nmpc_mul gives %i", inexact_t); 71 1.1 mrg fprintf (stderr, "\n"); 72 1.1 mrg exit (1); 73 1.1 mrg } 74 1.1 mrg 75 1.1 mrg mpc_set (t, x, MPC_RNDNN); 76 1.1 mrg inexact_t = mpc_sqr (t, t, rnd); 77 1.1 mrg if (mpc_cmp (z, t)) 78 1.1 mrg { 79 1.1 mrg fprintf (stderr, "sqr and sqr in place differ for rnd=(%s,%s) \nx=", 80 1.1 mrg mpfr_print_rnd_mode(MPC_RND_RE(rnd)), 81 1.1 mrg mpfr_print_rnd_mode(MPC_RND_IM(rnd))); 82 1.1 mrg mpc_out_str (stderr, 2, 0, x, MPC_RNDNN); 83 1.1 mrg fprintf (stderr, "\nmpc_sqr gives "); 84 1.1 mrg mpc_out_str (stderr, 2, 0, z, MPC_RNDNN); 85 1.1 mrg fprintf (stderr, "\nmpc_sqr in place gives "); 86 1.1 mrg mpc_out_str (stderr, 2, 0, t, MPC_RNDNN); 87 1.1 mrg fprintf (stderr, "\n"); 88 1.1 mrg exit (1); 89 1.1 mrg } 90 1.1 mrg if (inexact_z != inexact_t) 91 1.1 mrg { 92 1.1 mrg fprintf (stderr, "The return values of sqr and sqr in place differ for rnd=(%s,%s) \nx= ", 93 1.1 mrg mpfr_print_rnd_mode(MPC_RND_RE(rnd)), 94 1.1 mrg mpfr_print_rnd_mode(MPC_RND_IM(rnd))); 95 1.1 mrg mpc_out_str (stderr, 2, 0, x, MPC_RNDNN); 96 1.1 mrg fprintf (stderr, "\nx^2="); 97 1.1 mrg mpc_out_str (stderr, 2, 0, z, MPC_RNDNN); 98 1.1 mrg fprintf (stderr, "\nmpc_sqr gives %i", inexact_z); 99 1.1 mrg fprintf (stderr, "\nmpc_sqr in place gives %i", inexact_t); 100 1.1 mrg fprintf (stderr, "\n"); 101 1.1 mrg exit (1); 102 1.1 mrg } 103 1.1 mrg 104 1.1 mrg mpc_sqr (u, x, rnd); 105 1.1 mrg mpc_set (t, u, rnd); 106 1.1 mrg if (mpc_cmp (z, t)) 107 1.1 mrg { 108 1.1 mrg fprintf (stderr, "rounding in sqr might be incorrect for rnd=(%s,%s) \nx=", 109 1.1 mrg mpfr_print_rnd_mode(MPC_RND_RE(rnd)), 110 1.1 mrg mpfr_print_rnd_mode(MPC_RND_IM(rnd))); 111 1.1 mrg mpc_out_str (stderr, 2, 0, x, MPC_RNDNN); 112 1.1 mrg fprintf (stderr, "\nmpc_sqr gives "); 113 1.1 mrg mpc_out_str (stderr, 2, 0, z, MPC_RNDNN); 114 1.1 mrg fprintf (stderr, "\nmpc_sqr quadruple precision gives "); 115 1.1 mrg mpc_out_str (stderr, 2, 0, u, MPC_RNDNN); 116 1.1 mrg fprintf (stderr, "\nand is rounded to "); 117 1.1 mrg mpc_out_str (stderr, 2, 0, t, MPC_RNDNN); 118 1.1 mrg fprintf (stderr, "\n"); 119 1.1 mrg exit (1); 120 1.1 mrg } 121 1.1 mrg 122 1.1 mrg mpc_clear (z); 123 1.1 mrg mpc_clear (t); 124 1.1 mrg mpc_clear (u); 125 1.1 mrg } 126 1.1 mrg 127 1.1 mrg 128 1.1 mrg static void 129 1.1 mrg testsqr (long a, long b, mpfr_prec_t prec, mpc_rnd_t rnd) 130 1.1 mrg { 131 1.1 mrg mpc_t x; 132 1.1 mrg 133 1.1 mrg mpc_init2 (x, prec); 134 1.1 mrg 135 1.1 mrg mpc_set_si_si (x, a, b, rnd); 136 1.1 mrg 137 1.1 mrg cmpsqr (x, rnd); 138 1.1 mrg 139 1.1 mrg mpc_clear (x); 140 1.1 mrg } 141 1.1 mrg 142 1.1 mrg 143 1.1 mrg static void 144 1.1 mrg reuse_bug (void) 145 1.1 mrg { 146 1.1 mrg mpc_t z1; 147 1.1 mrg 148 1.1 mrg /* reuse bug found by Paul Zimmermann 20081021 */ 149 1.1 mrg mpc_init2 (z1, 2); 150 1.1 mrg /* RE (z1^2) overflows, IM(z^2) = -0 */ 151 1.1.1.2 mrg mpfr_set_str (mpc_realref (z1), "0.11", 2, MPFR_RNDN); 152 1.1.1.2 mrg mpfr_mul_2si (mpc_realref (z1), mpc_realref (z1), mpfr_get_emax (), MPFR_RNDN); 153 1.1.1.2 mrg mpfr_set_ui (mpc_imagref (z1), 0, MPFR_RNDN); 154 1.1 mrg mpc_conj (z1, z1, MPC_RNDNN); 155 1.1 mrg mpc_sqr (z1, z1, MPC_RNDNN); 156 1.1 mrg if (!mpfr_inf_p (mpc_realref (z1)) || mpfr_signbit (mpc_realref (z1)) 157 1.1 mrg ||!mpfr_zero_p (mpc_imagref (z1)) || !mpfr_signbit (mpc_imagref (z1))) 158 1.1 mrg { 159 1.1 mrg printf ("Error: Regression, bug 20081021 reproduced\n"); 160 1.1 mrg MPC_OUT (z1); 161 1.1 mrg exit (1); 162 1.1 mrg } 163 1.1 mrg 164 1.1 mrg mpc_clear (z1); 165 1.1 mrg } 166 1.1 mrg 167 1.1.1.2 mrg #define MPC_FUNCTION_CALL \ 168 1.1.1.2 mrg P[0].mpc_inex = mpc_sqr (P[1].mpc, P[2].mpc, P[3].mpc_rnd) 169 1.1.1.2 mrg #define MPC_FUNCTION_CALL_REUSE_OP1 \ 170 1.1.1.2 mrg P[0].mpc_inex = mpc_sqr (P[1].mpc, P[1].mpc, P[3].mpc_rnd) 171 1.1.1.2 mrg 172 1.1.1.2 mrg #include "data_check.tpl" 173 1.1.1.2 mrg #include "tgeneric.tpl" 174 1.1.1.2 mrg 175 1.1 mrg int 176 1.1 mrg main (void) 177 1.1 mrg { 178 1.1 mrg test_start (); 179 1.1 mrg 180 1.1 mrg testsqr (247, -65, 8, 24); 181 1.1 mrg testsqr (5, -896, 3, 2); 182 1.1 mrg testsqr (-3, -512, 2, 16); 183 1.1 mrg testsqr (266013312, 121990769, 27, 0); 184 1.1 mrg testsqr (170, 9, 8, 0); 185 1.1 mrg testsqr (768, 85, 8, 16); 186 1.1 mrg testsqr (145, 1816, 8, 24); 187 1.1 mrg testsqr (0, 1816, 8, 24); 188 1.1 mrg testsqr (145, 0, 8, 24); 189 1.1 mrg 190 1.1.1.2 mrg data_check_template ("sqr.dsc", "sqr.dat"); 191 1.1.1.2 mrg 192 1.1.1.2 mrg tgeneric_template ("sqr.dsc", 2, 1024, 1, 1024); 193 1.1 mrg 194 1.1 mrg reuse_bug (); 195 1.1 mrg 196 1.1 mrg test_end (); 197 1.1 mrg 198 1.1 mrg return 0; 199 1.1 mrg } 200