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