1/* Test file for mpfr_rec_sqrt. 2 3Copyright 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. 4Contributed by the AriC and Caramel projects, INRIA. 5 6This file is part of the GNU MPFR Library. 7 8The GNU MPFR Library is free software; you can redistribute it and/or modify 9it under the terms of the GNU Lesser General Public License as published by 10the Free Software Foundation; either version 3 of the License, or (at your 11option) any later version. 12 13The GNU MPFR Library is distributed in the hope that it will be useful, but 14WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 16License for more details. 17 18You should have received a copy of the GNU Lesser General Public License 19along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see 20http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., 2151 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ 22 23#include <stdio.h> 24#include <stdlib.h> 25 26#include "mpfr-test.h" 27 28#if MPFR_VERSION >= MPFR_VERSION_NUM(2,4,0) 29 30#define TEST_FUNCTION mpfr_rec_sqrt 31#define TEST_RANDOM_POS 8 /* 8/512 = 1/64 of the tested numbers are negative */ 32#include "tgeneric.c" 33 34static void 35special (void) 36{ 37 mpfr_t x, y; 38 int inex; 39 40 mpfr_init (x); 41 mpfr_init (y); 42 43 /* rec_sqrt(NaN) = NaN */ 44 mpfr_set_nan (x); 45 inex = mpfr_rec_sqrt (x, x, MPFR_RNDN); 46 MPFR_ASSERTN(mpfr_nan_p (x) && inex == 0); 47 48 /* rec_sqrt(+Inf) = +0 */ 49 mpfr_set_inf (x, 1); 50 inex = mpfr_rec_sqrt (x, x, MPFR_RNDN); 51 MPFR_ASSERTN(mpfr_zero_p (x) && MPFR_IS_POS(x) && inex == 0); 52 53 /* rec_sqrt(-Inf) = NaN */ 54 mpfr_set_inf (x, -1); 55 inex = mpfr_rec_sqrt (x, x, MPFR_RNDN); 56 MPFR_ASSERTN(mpfr_nan_p (x) && inex == 0); 57 58 /* rec_sqrt(+0) = +Inf */ 59 mpfr_set_ui (x, 0, MPFR_RNDN); 60 inex = mpfr_rec_sqrt (x, x, MPFR_RNDN); 61 MPFR_ASSERTN(mpfr_inf_p (x) && MPFR_IS_POS(x) && inex == 0); 62 63 /* rec_sqrt(-0) = +Inf */ 64 mpfr_set_ui (x, 0, MPFR_RNDN); 65 mpfr_neg (x, x, MPFR_RNDN); 66 inex = mpfr_rec_sqrt (x, x, MPFR_RNDN); 67 MPFR_ASSERTN(mpfr_inf_p (x) && MPFR_IS_POS(x) && inex == 0); 68 69 /* rec_sqrt(-1) = NaN */ 70 mpfr_set_si (x, -1, MPFR_RNDN); 71 inex = mpfr_rec_sqrt (x, x, MPFR_RNDN); 72 MPFR_ASSERTN(mpfr_nan_p (x) && inex == 0); 73 74 /* rec_sqrt(1) = 1 */ 75 mpfr_set_ui (x, 1, MPFR_RNDN); 76 inex = mpfr_rec_sqrt (x, x, MPFR_RNDN); 77 MPFR_ASSERTN((mpfr_cmp_ui (x, 1) == 0) && (inex == 0)); 78 79 mpfr_set_prec (x, 23); 80 mpfr_set_prec (y, 33); 81 mpfr_set_str_binary (x, "1.0001110110101001010100e-1"); 82 inex = mpfr_rec_sqrt (y, x, MPFR_RNDU); 83 mpfr_set_prec (x, 33); 84 mpfr_set_str_binary (x, "1.01010110101110100100100101011"); 85 MPFR_ASSERTN (inex > 0 && mpfr_cmp (x, y) == 0); 86 87 mpfr_clear (x); 88 mpfr_clear (y); 89} 90 91/* Worst case incorrectly rounded in r5573, found with the bad_cases test */ 92static void 93bad_case1 (void) 94{ 95 mpfr_t x, y, z; 96 97 mpfr_init2 (x, 72); 98 mpfr_inits2 (6, y, z, (mpfr_ptr) 0); 99 mpfr_set_str (x, "1.08310518720928b30e@-120", 16, MPFR_RNDN); 100 mpfr_set_str (z, "f.8@59", 16, MPFR_RNDN); 101 /* z = rec_sqrt(x) rounded on 6 bits toward 0, the exact value 102 being ~= f.bffffffffffffffffa11@59. */ 103 mpfr_rec_sqrt (y, x, MPFR_RNDZ); 104 if (mpfr_cmp0 (y, z) != 0) 105 { 106 printf ("Error in bad_case1\nexpected "); 107 mpfr_out_str (stdout, 16, 0, z, MPFR_RNDN); 108 printf ("\ngot "); 109 mpfr_out_str (stdout, 16, 0, y, MPFR_RNDN); 110 printf ("\n"); 111 exit (1); 112 } 113 mpfr_clears (x, y, z, (mpfr_ptr) 0); 114} 115 116static int 117pm2 (mpfr_ptr y, mpfr_srcptr x, mpfr_rnd_t rnd_mode) 118{ 119 return mpfr_pow_si (y, x, -2, rnd_mode); 120} 121 122/* exercises corner cases with inputs around 1 or 2 */ 123static void 124bad_case2 (void) 125{ 126 mpfr_t r, u; 127 mpfr_prec_t pr, pu; 128 int rnd; 129 130 for (pr = MPFR_PREC_MIN; pr <= 192; pr++) 131 for (pu = MPFR_PREC_MIN; pu <= 192; pu++) 132 { 133 mpfr_init2 (r, pr); 134 mpfr_init2 (u, pu); 135 136 mpfr_set_ui (u, 1, MPFR_RNDN); 137 for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) 138 mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd); 139 140 mpfr_nextbelow (u); 141 for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) 142 mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd); 143 144 mpfr_nextbelow (u); 145 for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) 146 mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd); 147 148 mpfr_set_ui (u, 1, MPFR_RNDN); 149 mpfr_nextabove (u); 150 for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) 151 mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd); 152 153 mpfr_nextabove (u); 154 for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) 155 mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd); 156 157 mpfr_set_ui (u, 2, MPFR_RNDN); 158 for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) 159 mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd); 160 161 mpfr_nextbelow (u); 162 for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) 163 mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd); 164 165 mpfr_nextbelow (u); 166 for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) 167 mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd); 168 169 mpfr_set_ui (u, 2, MPFR_RNDN); 170 mpfr_nextabove (u); 171 for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) 172 mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd); 173 174 mpfr_nextabove (u); 175 for (rnd = 0; rnd < MPFR_RND_MAX; rnd++) 176 mpfr_rec_sqrt (r, u, (mpfr_rnd_t) rnd); 177 178 mpfr_clear (r); 179 mpfr_clear (u); 180 } 181} 182 183int 184main (void) 185{ 186 tests_start_mpfr (); 187 188 special (); 189 bad_case1 (); 190 bad_case2 (); 191 test_generic (2, 300, 15); 192 193 data_check ("data/rec_sqrt", mpfr_rec_sqrt, "mpfr_rec_sqrt"); 194 bad_cases (mpfr_rec_sqrt, pm2, "mpfr_rec_sqrt", 8, -256, 255, 4, 128, 195 800, 50); 196 197 tests_end_mpfr (); 198 return 0; 199} 200 201#else /* MPFR_VERSION */ 202 203int 204main (void) 205{ 206 printf ("Warning! Test disabled for this MPFR version.\n"); 207 return 0; 208} 209 210#endif /* MPFR_VERSION */ 211