1/* Test file for mpfr_exp10. 2 3Copyright 2007, 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#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 34static void 35special_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 66static void 67emax_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 94static void 95exp_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 117static void 118overfl_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 195int 196main (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