1 /* Test file for mpfr_exp10. 2 3 Copyright 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc. 4 Contributed by the AriC and Caramel projects, INRIA. 5 6 This file is part of the GNU MPFR Library. 7 8 The GNU MPFR Library is free software; you can redistribute it and/or modify 9 it under the terms of the GNU Lesser General Public License as published by 10 the Free Software Foundation; either version 3 of the License, or (at your 11 option) any later version. 12 13 The GNU MPFR Library is distributed in the hope that it will be useful, but 14 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public 16 License for more details. 17 18 You should have received a copy of the GNU Lesser General Public License 19 along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see 20 http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc., 21 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */ 22 23 #include <stdio.h> 24 #include <stdlib.h> 25 #include <limits.h> 26 27 #include "mpfr-test.h" 28 29 #define TEST_FUNCTION mpfr_exp10 30 #define TEST_RANDOM_EMIN -36 31 #define TEST_RANDOM_EMAX 36 32 #include "tgeneric.c" 33 34 static void 35 special_overflow (void) 36 { 37 mpfr_t x, y; 38 int inex; 39 mpfr_exp_t emin, emax; 40 41 emin = mpfr_get_emin (); 42 emax = mpfr_get_emax (); 43 44 set_emin (-125); 45 set_emax (128); 46 47 mpfr_init2 (x, 24); 48 mpfr_init2 (y, 24); 49 50 mpfr_set_str_binary (x, "0.101100100000000000110100E15"); 51 inex = mpfr_exp10 (y, x, MPFR_RNDN); 52 if (!mpfr_inf_p (y) || inex <= 0) 53 { 54 printf ("Overflow error.\n"); 55 mpfr_dump (y); 56 printf ("inex = %d\n", inex); 57 exit (1); 58 } 59 60 mpfr_clear (y); 61 mpfr_clear (x); 62 set_emin (emin); 63 set_emax (emax); 64 } 65 66 static void 67 emax_m_eps (void) 68 { 69 if (mpfr_get_emax () <= LONG_MAX) 70 { 71 mpfr_t x, y; 72 int inex, ov; 73 74 mpfr_init2 (x, sizeof(mpfr_exp_t) * CHAR_BIT * 4); 75 mpfr_init2 (y, 8); 76 mpfr_set_si (x, mpfr_get_emax (), MPFR_RNDN); 77 78 mpfr_clear_flags (); 79 inex = mpfr_exp10 (y, x, MPFR_RNDN); 80 ov = mpfr_overflow_p (); 81 if (!ov || !mpfr_inf_p (y) || inex <= 0) 82 { 83 printf ("Overflow error for x = emax, MPFR_RNDN.\n"); 84 mpfr_dump (y); 85 printf ("inex = %d, %soverflow\n", inex, ov ? "" : "no "); 86 exit (1); 87 } 88 89 mpfr_clear (x); 90 mpfr_clear (y); 91 } 92 } 93 94 static void 95 exp_range (void) 96 { 97 mpfr_t x; 98 mpfr_exp_t emin; 99 100 emin = mpfr_get_emin (); 101 set_emin (3); 102 mpfr_init2 (x, 16); 103 mpfr_set_ui (x, 4, MPFR_RNDN); 104 mpfr_exp10 (x, x, MPFR_RNDN); 105 set_emin (emin); 106 if (mpfr_nan_p (x) || mpfr_cmp_ui (x, 10000) != 0) 107 { 108 printf ("Error in mpfr_exp10 for x = 4, with emin = 3\n"); 109 printf ("Expected 10000, got "); 110 mpfr_out_str (stdout, 2, 0, x, MPFR_RNDN); 111 printf ("\n"); 112 exit (1); 113 } 114 mpfr_clear (x); 115 } 116 117 static void 118 overfl_exp10_0 (void) 119 { 120 mpfr_t x, y; 121 int emax, i, inex, rnd, err = 0; 122 mpfr_exp_t old_emax; 123 124 old_emax = mpfr_get_emax (); 125 126 mpfr_init2 (x, 8); 127 mpfr_init2 (y, 8); 128 129 for (emax = -1; emax <= 0; emax++) 130 { 131 mpfr_set_ui_2exp (y, 1, emax, MPFR_RNDN); 132 mpfr_nextbelow (y); 133 set_emax (emax); /* 1 is not representable. */ 134 /* and if emax < 0, 1 - eps is not representable either. */ 135 for (i = -1; i <= 1; i++) 136 RND_LOOP (rnd) 137 { 138 mpfr_set_si_2exp (x, i, -512 * ABS (i), MPFR_RNDN); 139 mpfr_clear_flags (); 140 inex = mpfr_exp10 (x, x, (mpfr_rnd_t) rnd); 141 if ((i >= 0 || emax < 0 || rnd == MPFR_RNDN || rnd == MPFR_RNDU) && 142 ! mpfr_overflow_p ()) 143 { 144 printf ("Error in overfl_exp10_0 (i = %d, rnd = %s):\n" 145 " The overflow flag is not set.\n", 146 i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); 147 err = 1; 148 } 149 if (rnd == MPFR_RNDZ || rnd == MPFR_RNDD) 150 { 151 if (inex >= 0) 152 { 153 printf ("Error in overfl_exp10_0 (i = %d, rnd = %s):\n" 154 " The inexact value must be negative.\n", 155 i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); 156 err = 1; 157 } 158 if (! mpfr_equal_p (x, y)) 159 { 160 printf ("Error in overfl_exp10_0 (i = %d, rnd = %s):\n" 161 " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); 162 mpfr_print_binary (x); 163 printf (" instead of 0.11111111E%d.\n", emax); 164 err = 1; 165 } 166 } 167 else 168 { 169 if (inex <= 0) 170 { 171 printf ("Error in overfl_exp10_0 (i = %d, rnd = %s):\n" 172 " The inexact value must be positive.\n", 173 i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); 174 err = 1; 175 } 176 if (! (mpfr_inf_p (x) && MPFR_SIGN (x) > 0)) 177 { 178 printf ("Error in overfl_exp10_0 (i = %d, rnd = %s):\n" 179 " Got ", i, mpfr_print_rnd_mode ((mpfr_rnd_t) rnd)); 180 mpfr_print_binary (x); 181 printf (" instead of +Inf.\n"); 182 err = 1; 183 } 184 } 185 } 186 set_emax (old_emax); 187 } 188 189 if (err) 190 exit (1); 191 mpfr_clear (x); 192 mpfr_clear (y); 193 } 194 195 int 196 main (int argc, char *argv[]) 197 { 198 mpfr_t x, y; 199 mpfr_exp_t emin, emax; 200 int inex, ov; 201 202 tests_start_mpfr (); 203 204 special_overflow (); 205 emax_m_eps (); 206 exp_range (); 207 208 mpfr_init (x); 209 mpfr_init (y); 210 211 mpfr_set_ui (x, 4, MPFR_RNDN); 212 mpfr_exp10 (y, x, MPFR_RNDN); 213 if (mpfr_cmp_ui (y, 10000) != 0) 214 { 215 printf ("Error for 10^4, MPFR_RNDN\n"); 216 exit (1); 217 } 218 mpfr_exp10 (y, x, MPFR_RNDD); 219 if (mpfr_cmp_ui (y, 10000) != 0) 220 { 221 printf ("Error for 10^4, MPFR_RNDD\n"); 222 exit (1); 223 } 224 mpfr_exp10 (y, x, MPFR_RNDU); 225 if (mpfr_cmp_ui (y, 10000) != 0) 226 { 227 printf ("Error for 10^4, MPFR_RNDU\n"); 228 exit (1); 229 } 230 231 mpfr_set_prec (x, 10); 232 mpfr_set_prec (y, 10); 233 /* save emin */ 234 emin = mpfr_get_emin (); 235 set_emin (-11); 236 mpfr_set_si (x, -4, MPFR_RNDN); 237 mpfr_exp10 (y, x, MPFR_RNDN); 238 if (mpfr_cmp_ui (y, 0) || mpfr_sgn (y) < 0) 239 { 240 printf ("Error for emin = -11, x = -4, RNDN\n"); 241 printf ("Expected +0\n"); 242 printf ("Got "); mpfr_print_binary (y); puts (""); 243 exit (1); 244 } 245 /* restore emin */ 246 set_emin (emin); 247 248 /* save emax */ 249 emax = mpfr_get_emax (); 250 set_emax (13); 251 mpfr_set_ui (x, 4, MPFR_RNDN); 252 mpfr_exp10 (y, x, MPFR_RNDN); 253 if (!mpfr_inf_p (y) || mpfr_sgn (y) < 0) 254 { 255 printf ("Error for emax = 13, x = 4, RNDN\n"); 256 printf ("Expected +inf\n"); 257 printf ("Got "); mpfr_print_binary (y); puts (""); 258 exit (1); 259 } 260 /* restore emax */ 261 set_emax (emax); 262 263 MPFR_SET_INF (x); 264 MPFR_SET_POS (x); 265 mpfr_exp10 (y, x, MPFR_RNDN); 266 if (!MPFR_IS_INF (y)) 267 { 268 printf ("evaluation of function in INF does not return INF\n"); 269 exit (1); 270 } 271 272 MPFR_CHANGE_SIGN (x); 273 mpfr_exp10 (y, x, MPFR_RNDN); 274 if (!MPFR_IS_ZERO (y)) 275 { 276 printf ("evaluation of function in -INF does not return 0\n"); 277 exit (1); 278 } 279 280 MPFR_SET_NAN (x); 281 mpfr_exp10 (y, x, MPFR_RNDN); 282 if (!MPFR_IS_NAN (y)) 283 { 284 printf ("evaluation of function in NaN does not return NaN\n"); 285 exit (1); 286 } 287 288 if ((mpfr_uexp_t) 8 << 31 != 0 || 289 mpfr_get_emax () <= (mpfr_uexp_t) 100000 * 100000) 290 { 291 /* emax <= 10000000000 */ 292 mpfr_set_prec (x, 40); 293 mpfr_set_prec (y, 40); 294 mpfr_set_str (x, "3010299957", 10, MPFR_RNDN); 295 mpfr_clear_flags (); 296 inex = mpfr_exp10 (y, x, MPFR_RNDN); 297 ov = mpfr_overflow_p (); 298 if (!(MPFR_IS_INF (y) && MPFR_IS_POS (y) && ov)) 299 { 300 printf ("Overflow error for x = 3010299957, MPFR_RNDN.\n"); 301 mpfr_dump (y); 302 printf ("inex = %d, %soverflow\n", inex, ov ? "" : "no "); 303 exit (1); 304 } 305 } 306 307 test_generic (2, 100, 100); 308 309 mpfr_clear (x); 310 mpfr_clear (y); 311 312 overfl_exp10_0 (); 313 314 data_check ("data/exp10", mpfr_exp10, "mpfr_exp10"); 315 316 tests_end_mpfr (); 317 return 0; 318 } 319