1 /* Test file for mpfr_get_decimal64 and mpfr_set_decimal64. 2 3 Copyright 2006-2018 Free Software Foundation, Inc. 4 Contributed by the AriC and Caramba 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 #ifdef HAVE_CONFIG_H 24 # include "config.h" 25 #endif 26 27 #ifdef MPFR_WANT_DECIMAL_FLOATS 28 29 #include "mpfr-test.h" 30 31 #ifndef DEC64_MAX 32 # define DEC64_MAX 9.999999999999999E384dd 33 #endif 34 35 #if _MPFR_IEEE_FLOATS 36 static void 37 print_decimal64 (_Decimal64 d) 38 { 39 union mpfr_ieee_double_extract x; 40 union ieee_double_decimal64 y; 41 unsigned int Gh, i; 42 43 y.d64 = d; 44 x.d = y.d; 45 Gh = x.s.exp >> 6; 46 printf ("|%d%d%d%d%d%d", x.s.sig, Gh >> 4, (Gh >> 3) & 1, 47 (Gh >> 2) & 1, (Gh >> 1) & 1, Gh & 1); 48 printf ("%d%d%d%d%d%d", (x.s.exp >> 5) & 1, (x.s.exp >> 4) & 1, 49 (x.s.exp >> 3) & 1, (x.s.exp >> 2) & 1, (x.s.exp >> 1) & 1, 50 x.s.exp & 1); 51 for (i = 20; i > 0; i--) 52 printf ("%d", (x.s.manh >> (i - 1)) & 1); 53 for (i = 32; i > 0; i--) 54 printf ("%d", (x.s.manl >> (i - 1)) & 1); 55 printf ("|\n"); 56 } 57 #else 58 /* Portable version, assuming long double has at least 55 bits. 59 Note: __STDC_WANT_IEC_60559_DFP_EXT__ or __STDC_WANT_DEC_FP__ 60 might allow to use printf("%.15De\n", d) */ 61 static void 62 print_decimal64 (_Decimal64 d) 63 { 64 printf ("%.15Le\n", (long double) d); 65 } 66 #endif /* _MPFR_IEEE_FLOATS */ 67 68 #define PRINT_ERR_MISC(V) \ 69 do \ 70 { \ 71 printf ("Error in check_misc for %s.\n", V); \ 72 printf (" mpfr_get_decimal64() returned: "); \ 73 print_decimal64 (d); \ 74 printf (" mpfr_set_decimal64() set x to: "); \ 75 mpfr_out_str (stdout, 10, 0, x, MPFR_RNDN); \ 76 printf (" approx.\n = "); \ 77 mpfr_dump (x); \ 78 err = 1; \ 79 } \ 80 while (0) 81 82 static void 83 check_misc (void) 84 { 85 mpfr_t x, y; 86 _Decimal64 d; 87 int err = 0; 88 89 mpfr_init2 (x, 123); 90 mpfr_init2 (y, 123); 91 92 #if !defined(MPFR_ERRDIVZERO) 93 mpfr_set_nan (x); 94 d = mpfr_get_decimal64 (x, MPFR_RNDZ); 95 mpfr_set_ui (x, 1, MPFR_RNDZ); 96 mpfr_set_decimal64 (x, d, MPFR_RNDZ); 97 MPFR_ASSERTN (mpfr_nan_p (x)); 98 99 mpfr_set_inf (x, 1); 100 d = mpfr_get_decimal64 (x, MPFR_RNDZ); 101 mpfr_set_ui (x, 1, MPFR_RNDZ); 102 mpfr_set_decimal64 (x, d, MPFR_RNDZ); 103 if (! mpfr_inf_p (x) || MPFR_IS_NEG (x)) 104 PRINT_ERR_MISC ("+Inf"); 105 106 mpfr_set_inf (x, -1); 107 d = mpfr_get_decimal64 (x, MPFR_RNDZ); 108 mpfr_set_ui (x, 1, MPFR_RNDZ); 109 mpfr_set_decimal64 (x, d, MPFR_RNDZ); 110 if (! mpfr_inf_p (x) || MPFR_IS_POS (x)) 111 PRINT_ERR_MISC ("-Inf"); 112 #endif 113 114 mpfr_set_ui (x, 0, MPFR_RNDZ); 115 d = mpfr_get_decimal64 (x, MPFR_RNDZ); 116 mpfr_set_ui (x, 1, MPFR_RNDZ); 117 mpfr_set_decimal64 (x, d, MPFR_RNDZ); 118 if (MPFR_NOTZERO (x) || MPFR_IS_NEG (x)) 119 PRINT_ERR_MISC ("+0"); 120 121 mpfr_set_ui (x, 0, MPFR_RNDZ); 122 mpfr_neg (x, x, MPFR_RNDZ); 123 d = mpfr_get_decimal64 (x, MPFR_RNDZ); 124 mpfr_set_ui (x, 1, MPFR_RNDZ); 125 mpfr_set_decimal64 (x, d, MPFR_RNDZ); 126 if (MPFR_NOTZERO (x) || MPFR_IS_POS (x)) 127 PRINT_ERR_MISC ("-0"); 128 129 mpfr_set_ui (x, 1, MPFR_RNDZ); 130 d = mpfr_get_decimal64 (x, MPFR_RNDZ); 131 mpfr_set_ui (x, 0, MPFR_RNDZ); 132 mpfr_set_decimal64 (x, d, MPFR_RNDZ); 133 if (mpfr_cmp_ui (x, 1) != 0) 134 PRINT_ERR_MISC ("+1"); 135 136 mpfr_set_si (x, -1, MPFR_RNDZ); 137 d = mpfr_get_decimal64 (x, MPFR_RNDZ); 138 mpfr_set_ui (x, 0, MPFR_RNDZ); 139 mpfr_set_decimal64 (x, d, MPFR_RNDZ); 140 if (mpfr_cmp_si (x, -1) != 0) 141 PRINT_ERR_MISC ("-1"); 142 143 mpfr_set_ui (x, 2, MPFR_RNDZ); 144 d = mpfr_get_decimal64 (x, MPFR_RNDZ); 145 mpfr_set_ui (x, 0, MPFR_RNDZ); 146 mpfr_set_decimal64 (x, d, MPFR_RNDZ); 147 if (mpfr_cmp_ui (x, 2) != 0) 148 PRINT_ERR_MISC ("2"); 149 150 mpfr_set_ui (x, 99, MPFR_RNDZ); 151 d = mpfr_get_decimal64 (x, MPFR_RNDZ); 152 mpfr_set_ui (x, 0, MPFR_RNDZ); 153 mpfr_set_decimal64 (x, d, MPFR_RNDZ); 154 if (mpfr_cmp_ui (x, 99) != 0) 155 PRINT_ERR_MISC ("99"); 156 157 mpfr_set_str (x, "9999999999999999", 10, MPFR_RNDZ); 158 mpfr_set (y, x, MPFR_RNDZ); 159 d = mpfr_get_decimal64 (x, MPFR_RNDZ); 160 mpfr_set_ui (x, 0, MPFR_RNDZ); 161 mpfr_set_decimal64 (x, d, MPFR_RNDZ); 162 if (! mpfr_equal_p (x, y)) 163 PRINT_ERR_MISC ("9999999999999999"); 164 165 /* smallest normal number */ 166 mpfr_set_str (x, "1E-383", 10, MPFR_RNDU); 167 mpfr_set (y, x, MPFR_RNDZ); 168 d = mpfr_get_decimal64 (x, MPFR_RNDZ); 169 mpfr_set_ui (x, 0, MPFR_RNDZ); 170 mpfr_set_decimal64 (x, d, MPFR_RNDU); 171 if (! mpfr_equal_p (x, y)) 172 PRINT_ERR_MISC ("1E-383"); 173 174 /* smallest subnormal number */ 175 mpfr_set_str (x, "1E-398", 10, MPFR_RNDU); 176 mpfr_set (y, x, MPFR_RNDZ); 177 d = mpfr_get_decimal64 (x, MPFR_RNDZ); 178 mpfr_set_ui (x, 0, MPFR_RNDZ); 179 mpfr_set_decimal64 (x, d, MPFR_RNDU); 180 if (! mpfr_equal_p (x, y)) 181 PRINT_ERR_MISC ("1E-398"); 182 183 /* subnormal number with exponent change when we round back 184 from 16 digits to 1 digit */ 185 mpfr_set_str (x, "9.9E-398", 10, MPFR_RNDN); 186 d = mpfr_get_decimal64 (x, MPFR_RNDU); /* should be 1E-397 */ 187 mpfr_set_ui (x, 0, MPFR_RNDZ); 188 mpfr_set_decimal64 (x, d, MPFR_RNDD); 189 mpfr_set_str (y, "1E-397", 10, MPFR_RNDN); 190 if (! mpfr_equal_p (x, y)) 191 PRINT_ERR_MISC ("9.9E-398"); 192 193 /* largest number */ 194 mpfr_set_str (x, "9.999999999999999E384", 10, MPFR_RNDZ); 195 mpfr_set (y, x, MPFR_RNDZ); 196 d = mpfr_get_decimal64 (x, MPFR_RNDU); 197 if (d == DEC64_MAX) 198 { 199 mpfr_set_ui (x, 0, MPFR_RNDZ); 200 mpfr_set_decimal64 (x, d, MPFR_RNDZ); 201 if (! mpfr_equal_p (x, y)) 202 PRINT_ERR_MISC ("DEC64_MAX"); 203 } 204 else 205 { 206 printf ("Error in check_misc for DEC64_MAX.\n"); 207 printf (" mpfr_get_decimal64() returned: "); 208 print_decimal64 (d); 209 err = 1; 210 } 211 212 mpfr_set_str (x, "-9.999999999999999E384", 10, MPFR_RNDZ); 213 mpfr_set (y, x, MPFR_RNDZ); 214 d = mpfr_get_decimal64 (x, MPFR_RNDA); 215 if (d == -DEC64_MAX) 216 { 217 mpfr_set_ui (x, 0, MPFR_RNDZ); 218 mpfr_set_decimal64 (x, d, MPFR_RNDZ); 219 if (! mpfr_equal_p (x, y)) 220 PRINT_ERR_MISC ("-DEC64_MAX"); 221 } 222 else 223 { 224 printf ("Error in check_misc for -DEC64_MAX.\n"); 225 printf (" mpfr_get_decimal64() returned: "); 226 print_decimal64 (d); 227 err = 1; 228 } 229 230 mpfr_set_prec (x, 53); 231 mpfr_set_prec (y, 53); 232 233 /* largest number */ 234 mpfr_set_str (x, "9.999999999999999E384", 10, MPFR_RNDZ); 235 d = mpfr_get_decimal64 (x, MPFR_RNDZ); 236 mpfr_set_decimal64 (y, d, MPFR_RNDU); 237 if (! mpfr_equal_p (x, y)) 238 PRINT_ERR_MISC ("DEC64_MAX (2)"); 239 240 mpfr_clear (x); 241 mpfr_clear (y); 242 243 if (err) 244 exit (1); 245 } 246 247 static void 248 check_random (void) 249 { 250 mpfr_t x, y; 251 _Decimal64 d; 252 int i; 253 254 mpfr_init2 (x, 49); 255 mpfr_init2 (y, 49); 256 257 for (i = 0; i < 100000; i++) 258 { 259 mpfr_urandomb (x, RANDS); /* 0 <= x < 1 */ 260 /* the normal decimal64 range contains [2^(-1272), 2^1278] */ 261 mpfr_mul_2si (x, x, (i % 2550) - 1272, MPFR_RNDN); 262 if (mpfr_get_exp (x) <= -1272) 263 mpfr_mul_2exp (x, x, -1271 - mpfr_get_exp (x), MPFR_RNDN); 264 d = mpfr_get_decimal64 (x, MPFR_RNDN); 265 mpfr_set_decimal64 (y, d, MPFR_RNDN); 266 if (mpfr_cmp (x, y) != 0) 267 { 268 printf ("Error:\n"); 269 printf ("x="); mpfr_dump (x); 270 printf ("d="); print_decimal64 (d); 271 printf ("y="); mpfr_dump (y); 272 exit (1); 273 } 274 } 275 276 mpfr_clear (x); 277 mpfr_clear (y); 278 } 279 280 /* check with native decimal formats */ 281 static void 282 check_native (void) 283 { 284 mpfr_t x; 285 _Decimal64 d; 286 287 mpfr_init2 (x, 53); 288 289 /* check important constants are correctly converted */ 290 mpfr_set_ui (x, 17, MPFR_RNDN); 291 d = mpfr_get_decimal64 (x, MPFR_RNDN); 292 MPFR_ASSERTN(d == 17.0dd); 293 294 mpfr_set_ui (x, 42, MPFR_RNDN); 295 d = mpfr_get_decimal64 (x, MPFR_RNDN); 296 MPFR_ASSERTN(d == 42.0dd); 297 298 mpfr_set_decimal64 (x, 17.0dd, MPFR_RNDN); 299 MPFR_ASSERTN(mpfr_cmp_ui (x, 17) == 0); 300 301 mpfr_set_decimal64 (x, 42.0dd, MPFR_RNDN); 302 MPFR_ASSERTN(mpfr_cmp_ui (x, 42) == 0); 303 304 mpfr_clear (x); 305 } 306 307 static void 308 check_overflow (void) 309 { 310 mpfr_t x; 311 int err = 0, neg, rnd; 312 313 mpfr_init2 (x, 96); 314 for (neg = 0; neg < 2; neg++) 315 RND_LOOP (rnd) 316 { 317 _Decimal64 d, e; 318 mpfr_rnd_t r = (mpfr_rnd_t) rnd; 319 int sign = neg ? -1 : 1; 320 321 e = sign * (MPFR_IS_LIKE_RNDZ (r, neg) ? 1 : 2) * DEC64_MAX; 322 /* This tests the binary exponent e > 1279 case of get_d64.c */ 323 mpfr_set_si_2exp (x, sign, 9999, MPFR_RNDN); 324 d = mpfr_get_decimal64 (x, r); 325 if (d != e) 326 { 327 printf ("Error 1 in check_overflow for %s, %s\n", 328 neg ? "negative" : "positive", 329 mpfr_print_rnd_mode (r)); 330 err = 1; 331 } 332 /* This tests the decimal exponent e > 385 case of get_d64.c */ 333 mpfr_set_si_2exp (x, sign * 31, 1274, MPFR_RNDN); 334 d = mpfr_get_decimal64 (x, r); 335 if (d != e) 336 { 337 printf ("Error 2 in check_overflow for %s, %s\n", 338 neg ? "negative" : "positive", 339 mpfr_print_rnd_mode (r)); 340 err = 1; 341 } 342 /* This tests the last else (-382 <= e <= 385) of get_d64.c */ 343 mpfr_set_decimal64 (x, e, MPFR_RNDA); 344 d = mpfr_get_decimal64 (x, r); 345 if (d != e) 346 { 347 printf ("Error 3 in check_overflow for %s, %s\n", 348 neg ? "negative" : "positive", 349 mpfr_print_rnd_mode (r)); 350 err = 1; 351 } 352 } 353 mpfr_clear (x); 354 if (err) 355 exit (1); 356 } 357 358 static void 359 check_tiny (void) 360 { 361 mpfr_t x; 362 _Decimal64 d; 363 364 /* If 0.5E-398 < |x| < 1E-398 (smallest subnormal), x should round 365 to +/- 1E-398 in MPFR_RNDN. Note: the midpoint 0.5E-398 between 366 0 and 1E-398 is not a representable binary number, so that there 367 are no tests for it. */ 368 mpfr_init2 (x, 128); 369 mpfr_set_str (x, "1E-398", 10, MPFR_RNDZ); 370 d = mpfr_get_decimal64 (x, MPFR_RNDN); 371 MPFR_ASSERTN (d == 1.0E-398dd); 372 mpfr_neg (x, x, MPFR_RNDN); 373 d = mpfr_get_decimal64 (x, MPFR_RNDN); 374 MPFR_ASSERTN (d == -1.0E-398dd); 375 mpfr_set_str (x, "0.5E-398", 10, MPFR_RNDU); 376 d = mpfr_get_decimal64 (x, MPFR_RNDN); 377 MPFR_ASSERTN (d == 1.0E-398dd); 378 mpfr_neg (x, x, MPFR_RNDN); 379 d = mpfr_get_decimal64 (x, MPFR_RNDN); 380 MPFR_ASSERTN (d == -1.0E-398dd); 381 mpfr_clear (x); 382 } 383 384 int 385 main (void) 386 { 387 tests_start_mpfr (); 388 mpfr_test_init (); 389 390 #ifdef MPFR_DEBUG 391 #ifdef DPD_FORMAT 392 printf ("Using DPD format\n"); 393 #else 394 printf ("Using BID format\n"); 395 #endif 396 #endif 397 check_misc (); 398 check_random (); 399 check_native (); 400 #if !defined(MPFR_ERRDIVZERO) 401 check_overflow (); 402 #endif 403 check_tiny (); 404 405 tests_end_mpfr (); 406 return 0; 407 } 408 409 #else /* MPFR_WANT_DECIMAL_FLOATS */ 410 411 int 412 main (void) 413 { 414 return 77; 415 } 416 417 #endif /* MPFR_WANT_DECIMAL_FLOATS */ 418