14a238c70SJohn Marino /* mpfr_get_decimal64 -- convert a multiple precision floating-point number
24a238c70SJohn Marino to a IEEE 754r decimal64 float
34a238c70SJohn Marino
44a238c70SJohn Marino See http://gcc.gnu.org/ml/gcc/2006-06/msg00691.html,
54a238c70SJohn Marino http://gcc.gnu.org/onlinedocs/gcc/Decimal-Float.html,
64a238c70SJohn Marino and TR 24732 <http://www.open-std.org/jtc1/sc22/wg14/www/projects#24732>.
74a238c70SJohn Marino
8*ab6d115fSJohn Marino Copyright 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Free Software Foundation, Inc.
9*ab6d115fSJohn Marino Contributed by the AriC and Caramel projects, INRIA.
104a238c70SJohn Marino
114a238c70SJohn Marino This file is part of the GNU MPFR Library.
124a238c70SJohn Marino
134a238c70SJohn Marino The GNU MPFR Library is free software; you can redistribute it and/or modify
144a238c70SJohn Marino it under the terms of the GNU Lesser General Public License as published by
154a238c70SJohn Marino the Free Software Foundation; either version 3 of the License, or (at your
164a238c70SJohn Marino option) any later version.
174a238c70SJohn Marino
184a238c70SJohn Marino The GNU MPFR Library is distributed in the hope that it will be useful, but
194a238c70SJohn Marino WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
204a238c70SJohn Marino or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
214a238c70SJohn Marino License for more details.
224a238c70SJohn Marino
234a238c70SJohn Marino You should have received a copy of the GNU Lesser General Public License
244a238c70SJohn Marino along with the GNU MPFR Library; see the file COPYING.LESSER. If not, see
254a238c70SJohn Marino http://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
264a238c70SJohn Marino 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
274a238c70SJohn Marino
284a238c70SJohn Marino #include <stdlib.h> /* for strtol */
294a238c70SJohn Marino #include "mpfr-impl.h"
304a238c70SJohn Marino
314a238c70SJohn Marino #define ISDIGIT(c) ('0' <= c && c <= '9')
324a238c70SJohn Marino
334a238c70SJohn Marino #ifdef MPFR_WANT_DECIMAL_FLOATS
344a238c70SJohn Marino
35*ab6d115fSJohn Marino #ifndef DEC64_MAX
36*ab6d115fSJohn Marino # define DEC64_MAX 9.999999999999999E384dd
37*ab6d115fSJohn Marino #endif
38*ab6d115fSJohn Marino
394a238c70SJohn Marino #ifdef DPD_FORMAT
404a238c70SJohn Marino static int T[1000] = {
414a238c70SJohn Marino 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 32,
424a238c70SJohn Marino 33, 34, 35, 36, 37, 38, 39, 40, 41, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57,
434a238c70SJohn Marino 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 80, 81, 82, 83, 84, 85, 86, 87, 88,
444a238c70SJohn Marino 89, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 112, 113, 114, 115, 116,
454a238c70SJohn Marino 117, 118, 119, 120, 121, 10, 11, 42, 43, 74, 75, 106, 107, 78, 79, 26, 27,
464a238c70SJohn Marino 58, 59, 90, 91, 122, 123, 94, 95, 128, 129, 130, 131, 132, 133, 134, 135,
474a238c70SJohn Marino 136, 137, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 160, 161, 162,
484a238c70SJohn Marino 163, 164, 165, 166, 167, 168, 169, 176, 177, 178, 179, 180, 181, 182, 183,
494a238c70SJohn Marino 184, 185, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 208, 209, 210,
504a238c70SJohn Marino 211, 212, 213, 214, 215, 216, 217, 224, 225, 226, 227, 228, 229, 230, 231,
514a238c70SJohn Marino 232, 233, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 138, 139, 170,
524a238c70SJohn Marino 171, 202, 203, 234, 235, 206, 207, 154, 155, 186, 187, 218, 219, 250, 251,
534a238c70SJohn Marino 222, 223, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, 272, 273, 274,
544a238c70SJohn Marino 275, 276, 277, 278, 279, 280, 281, 288, 289, 290, 291, 292, 293, 294, 295,
554a238c70SJohn Marino 296, 297, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 320, 321, 322,
564a238c70SJohn Marino 323, 324, 325, 326, 327, 328, 329, 336, 337, 338, 339, 340, 341, 342, 343,
574a238c70SJohn Marino 344, 345, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 368, 369, 370,
584a238c70SJohn Marino 371, 372, 373, 374, 375, 376, 377, 266, 267, 298, 299, 330, 331, 362, 363,
594a238c70SJohn Marino 334, 335, 282, 283, 314, 315, 346, 347, 378, 379, 350, 351, 384, 385, 386,
604a238c70SJohn Marino 387, 388, 389, 390, 391, 392, 393, 400, 401, 402, 403, 404, 405, 406, 407,
614a238c70SJohn Marino 408, 409, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 432, 433, 434,
624a238c70SJohn Marino 435, 436, 437, 438, 439, 440, 441, 448, 449, 450, 451, 452, 453, 454, 455,
634a238c70SJohn Marino 456, 457, 464, 465, 466, 467, 468, 469, 470, 471, 472, 473, 480, 481, 482,
644a238c70SJohn Marino 483, 484, 485, 486, 487, 488, 489, 496, 497, 498, 499, 500, 501, 502, 503,
654a238c70SJohn Marino 504, 505, 394, 395, 426, 427, 458, 459, 490, 491, 462, 463, 410, 411, 442,
664a238c70SJohn Marino 443, 474, 475, 506, 507, 478, 479, 512, 513, 514, 515, 516, 517, 518, 519,
674a238c70SJohn Marino 520, 521, 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, 544, 545, 546,
684a238c70SJohn Marino 547, 548, 549, 550, 551, 552, 553, 560, 561, 562, 563, 564, 565, 566, 567,
694a238c70SJohn Marino 568, 569, 576, 577, 578, 579, 580, 581, 582, 583, 584, 585, 592, 593, 594,
704a238c70SJohn Marino 595, 596, 597, 598, 599, 600, 601, 608, 609, 610, 611, 612, 613, 614, 615,
714a238c70SJohn Marino 616, 617, 624, 625, 626, 627, 628, 629, 630, 631, 632, 633, 522, 523, 554,
724a238c70SJohn Marino 555, 586, 587, 618, 619, 590, 591, 538, 539, 570, 571, 602, 603, 634, 635,
734a238c70SJohn Marino 606, 607, 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 656, 657, 658,
744a238c70SJohn Marino 659, 660, 661, 662, 663, 664, 665, 672, 673, 674, 675, 676, 677, 678, 679,
754a238c70SJohn Marino 680, 681, 688, 689, 690, 691, 692, 693, 694, 695, 696, 697, 704, 705, 706,
764a238c70SJohn Marino 707, 708, 709, 710, 711, 712, 713, 720, 721, 722, 723, 724, 725, 726, 727,
774a238c70SJohn Marino 728, 729, 736, 737, 738, 739, 740, 741, 742, 743, 744, 745, 752, 753, 754,
784a238c70SJohn Marino 755, 756, 757, 758, 759, 760, 761, 650, 651, 682, 683, 714, 715, 746, 747,
794a238c70SJohn Marino 718, 719, 666, 667, 698, 699, 730, 731, 762, 763, 734, 735, 768, 769, 770,
804a238c70SJohn Marino 771, 772, 773, 774, 775, 776, 777, 784, 785, 786, 787, 788, 789, 790, 791,
814a238c70SJohn Marino 792, 793, 800, 801, 802, 803, 804, 805, 806, 807, 808, 809, 816, 817, 818,
824a238c70SJohn Marino 819, 820, 821, 822, 823, 824, 825, 832, 833, 834, 835, 836, 837, 838, 839,
834a238c70SJohn Marino 840, 841, 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 864, 865, 866,
844a238c70SJohn Marino 867, 868, 869, 870, 871, 872, 873, 880, 881, 882, 883, 884, 885, 886, 887,
854a238c70SJohn Marino 888, 889, 778, 779, 810, 811, 842, 843, 874, 875, 846, 847, 794, 795, 826,
864a238c70SJohn Marino 827, 858, 859, 890, 891, 862, 863, 896, 897, 898, 899, 900, 901, 902, 903,
874a238c70SJohn Marino 904, 905, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 928, 929, 930,
884a238c70SJohn Marino 931, 932, 933, 934, 935, 936, 937, 944, 945, 946, 947, 948, 949, 950, 951,
894a238c70SJohn Marino 952, 953, 960, 961, 962, 963, 964, 965, 966, 967, 968, 969, 976, 977, 978,
904a238c70SJohn Marino 979, 980, 981, 982, 983, 984, 985, 992, 993, 994, 995, 996, 997, 998, 999,
914a238c70SJohn Marino 1000, 1001, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, 1016, 1017, 906,
924a238c70SJohn Marino 907, 938, 939, 970, 971, 1002, 1003, 974, 975, 922, 923, 954, 955, 986,
934a238c70SJohn Marino 987, 1018, 1019, 990, 991, 12, 13, 268, 269, 524, 525, 780, 781, 46, 47, 28,
944a238c70SJohn Marino 29, 284, 285, 540, 541, 796, 797, 62, 63, 44, 45, 300, 301, 556, 557, 812,
954a238c70SJohn Marino 813, 302, 303, 60, 61, 316, 317, 572, 573, 828, 829, 318, 319, 76, 77,
964a238c70SJohn Marino 332, 333, 588, 589, 844, 845, 558, 559, 92, 93, 348, 349, 604, 605, 860,
974a238c70SJohn Marino 861, 574, 575, 108, 109, 364, 365, 620, 621, 876, 877, 814, 815, 124, 125,
984a238c70SJohn Marino 380, 381, 636, 637, 892, 893, 830, 831, 14, 15, 270, 271, 526, 527, 782,
994a238c70SJohn Marino 783, 110, 111, 30, 31, 286, 287, 542, 543, 798, 799, 126, 127, 140, 141,
1004a238c70SJohn Marino 396, 397, 652, 653, 908, 909, 174, 175, 156, 157, 412, 413, 668, 669, 924,
1014a238c70SJohn Marino 925, 190, 191, 172, 173, 428, 429, 684, 685, 940, 941, 430, 431, 188, 189,
1024a238c70SJohn Marino 444, 445, 700, 701, 956, 957, 446, 447, 204, 205, 460, 461, 716, 717, 972,
1034a238c70SJohn Marino 973, 686, 687, 220, 221, 476, 477, 732, 733, 988, 989, 702, 703, 236, 237,
1044a238c70SJohn Marino 492, 493, 748, 749, 1004, 1005, 942, 943, 252, 253, 508, 509, 764, 765,
1054a238c70SJohn Marino 1020, 1021, 958, 959, 142, 143, 398, 399, 654, 655, 910, 911, 238, 239, 158,
1064a238c70SJohn Marino 159, 414, 415, 670, 671, 926, 927, 254, 255};
1074a238c70SJohn Marino #endif
1084a238c70SJohn Marino
1094a238c70SJohn Marino /* construct a decimal64 NaN */
1104a238c70SJohn Marino static _Decimal64
get_decimal64_nan(void)1114a238c70SJohn Marino get_decimal64_nan (void)
1124a238c70SJohn Marino {
1134a238c70SJohn Marino union ieee_double_extract x;
1144a238c70SJohn Marino union ieee_double_decimal64 y;
1154a238c70SJohn Marino
1164a238c70SJohn Marino x.s.exp = 1984; /* G[0]..G[4] = 11111: quiet NaN */
1174a238c70SJohn Marino y.d = x.d;
1184a238c70SJohn Marino return y.d64;
1194a238c70SJohn Marino }
1204a238c70SJohn Marino
1214a238c70SJohn Marino /* construct the decimal64 Inf with given sign */
1224a238c70SJohn Marino static _Decimal64
get_decimal64_inf(int negative)1234a238c70SJohn Marino get_decimal64_inf (int negative)
1244a238c70SJohn Marino {
1254a238c70SJohn Marino union ieee_double_extract x;
1264a238c70SJohn Marino union ieee_double_decimal64 y;
1274a238c70SJohn Marino
1284a238c70SJohn Marino x.s.sig = (negative) ? 1 : 0;
1294a238c70SJohn Marino x.s.exp = 1920; /* G[0]..G[4] = 11110: Inf */
1304a238c70SJohn Marino y.d = x.d;
1314a238c70SJohn Marino return y.d64;
1324a238c70SJohn Marino }
1334a238c70SJohn Marino
1344a238c70SJohn Marino /* construct the decimal64 zero with given sign */
1354a238c70SJohn Marino static _Decimal64
get_decimal64_zero(int negative)1364a238c70SJohn Marino get_decimal64_zero (int negative)
1374a238c70SJohn Marino {
1384a238c70SJohn Marino union ieee_double_decimal64 y;
1394a238c70SJohn Marino
1404a238c70SJohn Marino /* zero has the same representation in binary64 and decimal64 */
1414a238c70SJohn Marino y.d = negative ? DBL_NEG_ZERO : 0.0;
1424a238c70SJohn Marino return y.d64;
1434a238c70SJohn Marino }
1444a238c70SJohn Marino
1454a238c70SJohn Marino /* construct the decimal64 smallest non-zero with given sign */
1464a238c70SJohn Marino static _Decimal64
get_decimal64_min(int negative)1474a238c70SJohn Marino get_decimal64_min (int negative)
1484a238c70SJohn Marino {
149*ab6d115fSJohn Marino return negative ? - 1E-398dd : 1E-398dd;
1504a238c70SJohn Marino }
1514a238c70SJohn Marino
1524a238c70SJohn Marino /* construct the decimal64 largest finite number with given sign */
1534a238c70SJohn Marino static _Decimal64
get_decimal64_max(int negative)1544a238c70SJohn Marino get_decimal64_max (int negative)
1554a238c70SJohn Marino {
156*ab6d115fSJohn Marino return negative ? - DEC64_MAX : DEC64_MAX;
1574a238c70SJohn Marino }
1584a238c70SJohn Marino
1594a238c70SJohn Marino /* one-to-one conversion:
1604a238c70SJohn Marino s is a decimal string representing a number x = m * 10^e which must be
1614a238c70SJohn Marino exactly representable in the decimal64 format, i.e.
1624a238c70SJohn Marino (a) the mantissa m has at most 16 decimal digits
1634a238c70SJohn Marino (b1) -383 <= e <= 384 with m integer multiple of 10^(-15), |m| < 10
1644a238c70SJohn Marino (b2) or -398 <= e <= 369 with m integer, |m| < 10^16.
1654a238c70SJohn Marino Assumes s is neither NaN nor +Inf nor -Inf.
1664a238c70SJohn Marino */
1674a238c70SJohn Marino static _Decimal64
string_to_Decimal64(char * s)1684a238c70SJohn Marino string_to_Decimal64 (char *s)
1694a238c70SJohn Marino {
1704a238c70SJohn Marino long int exp = 0;
1714a238c70SJohn Marino char m[17];
1724a238c70SJohn Marino long n = 0; /* mantissa length */
1734a238c70SJohn Marino char *endptr[1];
1744a238c70SJohn Marino union ieee_double_extract x;
1754a238c70SJohn Marino union ieee_double_decimal64 y;
1764a238c70SJohn Marino #ifdef DPD_FORMAT
1774a238c70SJohn Marino unsigned int G, d1, d2, d3, d4, d5;
1784a238c70SJohn Marino #endif
1794a238c70SJohn Marino
1804a238c70SJohn Marino /* read sign */
1814a238c70SJohn Marino if (*s == '-')
1824a238c70SJohn Marino {
1834a238c70SJohn Marino x.s.sig = 1;
1844a238c70SJohn Marino s ++;
1854a238c70SJohn Marino }
1864a238c70SJohn Marino else
1874a238c70SJohn Marino x.s.sig = 0;
1884a238c70SJohn Marino /* read mantissa */
1894a238c70SJohn Marino while (ISDIGIT (*s))
1904a238c70SJohn Marino m[n++] = *s++;
1914a238c70SJohn Marino exp = n;
1924a238c70SJohn Marino if (*s == '.')
1934a238c70SJohn Marino {
1944a238c70SJohn Marino s ++;
1954a238c70SJohn Marino while (ISDIGIT (*s))
1964a238c70SJohn Marino m[n++] = *s++;
1974a238c70SJohn Marino }
1984a238c70SJohn Marino /* we have exp digits before decimal point, and a total of n digits */
1994a238c70SJohn Marino exp -= n; /* we will consider an integer mantissa */
2004a238c70SJohn Marino MPFR_ASSERTN(n <= 16);
2014a238c70SJohn Marino if (*s == 'E' || *s == 'e')
2024a238c70SJohn Marino exp += strtol (s + 1, endptr, 10);
2034a238c70SJohn Marino else
2044a238c70SJohn Marino *endptr = s;
2054a238c70SJohn Marino MPFR_ASSERTN(**endptr == '\0');
2064a238c70SJohn Marino MPFR_ASSERTN(-398 <= exp && exp <= (long) (385 - n));
2074a238c70SJohn Marino while (n < 16)
2084a238c70SJohn Marino {
2094a238c70SJohn Marino m[n++] = '0';
2104a238c70SJohn Marino exp --;
2114a238c70SJohn Marino }
2124a238c70SJohn Marino /* now n=16 and -398 <= exp <= 369 */
2134a238c70SJohn Marino m[n] = '\0';
2144a238c70SJohn Marino
2154a238c70SJohn Marino /* compute biased exponent */
2164a238c70SJohn Marino exp += 398;
2174a238c70SJohn Marino
2184a238c70SJohn Marino MPFR_ASSERTN(exp >= -15);
2194a238c70SJohn Marino if (exp < 0)
2204a238c70SJohn Marino {
2214a238c70SJohn Marino int i;
2224a238c70SJohn Marino n = -exp;
2234a238c70SJohn Marino /* check the last n digits of the mantissa are zero */
2244a238c70SJohn Marino for (i = 1; i <= n; i++)
2254a238c70SJohn Marino MPFR_ASSERTN(m[16 - n] == '0');
2264a238c70SJohn Marino /* shift the first (16-n) digits to the right */
2274a238c70SJohn Marino for (i = 16 - n - 1; i >= 0; i--)
2284a238c70SJohn Marino m[i + n] = m[i];
2294a238c70SJohn Marino /* zero the first n digits */
2304a238c70SJohn Marino for (i = 0; i < n; i ++)
2314a238c70SJohn Marino m[i] = '0';
2324a238c70SJohn Marino exp = 0;
2334a238c70SJohn Marino }
2344a238c70SJohn Marino
2354a238c70SJohn Marino /* now convert to DPD or BID */
2364a238c70SJohn Marino #ifdef DPD_FORMAT
2374a238c70SJohn Marino #define CH(d) (d - '0')
2384a238c70SJohn Marino if (m[0] >= '8')
2394a238c70SJohn Marino G = (3 << 11) | ((exp & 768) << 1) | ((CH(m[0]) & 1) << 8);
2404a238c70SJohn Marino else
2414a238c70SJohn Marino G = ((exp & 768) << 3) | (CH(m[0]) << 8);
2424a238c70SJohn Marino /* now the most 5 significant bits of G are filled */
2434a238c70SJohn Marino G |= exp & 255;
2444a238c70SJohn Marino d1 = T[100 * CH(m[1]) + 10 * CH(m[2]) + CH(m[3])]; /* 10-bit encoding */
2454a238c70SJohn Marino d2 = T[100 * CH(m[4]) + 10 * CH(m[5]) + CH(m[6])]; /* 10-bit encoding */
2464a238c70SJohn Marino d3 = T[100 * CH(m[7]) + 10 * CH(m[8]) + CH(m[9])]; /* 10-bit encoding */
2474a238c70SJohn Marino d4 = T[100 * CH(m[10]) + 10 * CH(m[11]) + CH(m[12])]; /* 10-bit encoding */
2484a238c70SJohn Marino d5 = T[100 * CH(m[13]) + 10 * CH(m[14]) + CH(m[15])]; /* 10-bit encoding */
2494a238c70SJohn Marino x.s.exp = G >> 2;
2504a238c70SJohn Marino x.s.manh = ((G & 3) << 18) | (d1 << 8) | (d2 >> 2);
2514a238c70SJohn Marino x.s.manl = (d2 & 3) << 30;
2524a238c70SJohn Marino x.s.manl |= (d3 << 20) | (d4 << 10) | d5;
2534a238c70SJohn Marino #else /* BID format */
2544a238c70SJohn Marino {
2554a238c70SJohn Marino mp_size_t rn;
2564a238c70SJohn Marino mp_limb_t rp[2];
2574a238c70SJohn Marino int case_i = strcmp (m, "9007199254740992") < 0;
2584a238c70SJohn Marino
2594a238c70SJohn Marino for (n = 0; n < 16; n++)
2604a238c70SJohn Marino m[n] -= '0';
2614a238c70SJohn Marino rn = mpn_set_str (rp, (unsigned char *) m, 16, 10);
2624a238c70SJohn Marino if (rn == 1)
2634a238c70SJohn Marino rp[1] = 0;
2644a238c70SJohn Marino #if GMP_NUMB_BITS > 32
2654a238c70SJohn Marino rp[1] = rp[1] << (GMP_NUMB_BITS - 32);
2664a238c70SJohn Marino rp[1] |= rp[0] >> 32;
2674a238c70SJohn Marino rp[0] &= 4294967295UL;
2684a238c70SJohn Marino #endif
2694a238c70SJohn Marino if (case_i)
2704a238c70SJohn Marino { /* s < 2^53: case i) */
2714a238c70SJohn Marino x.s.exp = exp << 1;
2724a238c70SJohn Marino x.s.manl = rp[0]; /* 32 bits */
2734a238c70SJohn Marino x.s.manh = rp[1] & 1048575; /* 20 low bits */
2744a238c70SJohn Marino x.s.exp |= rp[1] >> 20; /* 1 bit */
2754a238c70SJohn Marino }
2764a238c70SJohn Marino else /* s >= 2^53: case ii) */
2774a238c70SJohn Marino {
2784a238c70SJohn Marino x.s.exp = 1536 | (exp >> 1);
2794a238c70SJohn Marino x.s.manl = rp[0];
2804a238c70SJohn Marino x.s.manh = (rp[1] ^ 2097152) | ((exp & 1) << 19);
2814a238c70SJohn Marino }
2824a238c70SJohn Marino }
2834a238c70SJohn Marino #endif /* DPD_FORMAT */
2844a238c70SJohn Marino y.d = x.d;
2854a238c70SJohn Marino return y.d64;
2864a238c70SJohn Marino }
2874a238c70SJohn Marino
2884a238c70SJohn Marino _Decimal64
mpfr_get_decimal64(mpfr_srcptr src,mpfr_rnd_t rnd_mode)2894a238c70SJohn Marino mpfr_get_decimal64 (mpfr_srcptr src, mpfr_rnd_t rnd_mode)
2904a238c70SJohn Marino {
2914a238c70SJohn Marino int negative;
2924a238c70SJohn Marino mpfr_exp_t e;
2934a238c70SJohn Marino
2944a238c70SJohn Marino /* the encoding of NaN, Inf, zero is the same under DPD or BID */
2954a238c70SJohn Marino if (MPFR_UNLIKELY (MPFR_IS_SINGULAR (src)))
2964a238c70SJohn Marino {
2974a238c70SJohn Marino if (MPFR_IS_NAN (src))
2984a238c70SJohn Marino return get_decimal64_nan ();
2994a238c70SJohn Marino
3004a238c70SJohn Marino negative = MPFR_IS_NEG (src);
3014a238c70SJohn Marino
3024a238c70SJohn Marino if (MPFR_IS_INF (src))
3034a238c70SJohn Marino return get_decimal64_inf (negative);
3044a238c70SJohn Marino
3054a238c70SJohn Marino MPFR_ASSERTD (MPFR_IS_ZERO(src));
3064a238c70SJohn Marino return get_decimal64_zero (negative);
3074a238c70SJohn Marino }
3084a238c70SJohn Marino
3094a238c70SJohn Marino e = MPFR_GET_EXP (src);
3104a238c70SJohn Marino negative = MPFR_IS_NEG (src);
3114a238c70SJohn Marino
3124a238c70SJohn Marino if (MPFR_UNLIKELY(rnd_mode == MPFR_RNDA))
3134a238c70SJohn Marino rnd_mode = negative ? MPFR_RNDD : MPFR_RNDU;
3144a238c70SJohn Marino
3154a238c70SJohn Marino /* the smallest decimal64 number is 10^(-398),
3164a238c70SJohn Marino with 2^(-1323) < 10^(-398) < 2^(-1322) */
3174a238c70SJohn Marino if (MPFR_UNLIKELY (e < -1323)) /* src <= 2^(-1324) < 1/2*10^(-398) */
3184a238c70SJohn Marino {
3194a238c70SJohn Marino if (rnd_mode == MPFR_RNDZ || rnd_mode == MPFR_RNDN
3204a238c70SJohn Marino || (rnd_mode == MPFR_RNDD && negative == 0)
3214a238c70SJohn Marino || (rnd_mode == MPFR_RNDU && negative != 0))
3224a238c70SJohn Marino return get_decimal64_zero (negative);
3234a238c70SJohn Marino else /* return the smallest non-zero number */
3244a238c70SJohn Marino return get_decimal64_min (negative);
3254a238c70SJohn Marino }
3264a238c70SJohn Marino /* the largest decimal64 number is just below 10^(385) < 2^1279 */
3274a238c70SJohn Marino else if (MPFR_UNLIKELY (e > 1279)) /* then src >= 2^1279 */
3284a238c70SJohn Marino {
329*ab6d115fSJohn Marino if (rnd_mode == MPFR_RNDZ
330*ab6d115fSJohn Marino || (rnd_mode == MPFR_RNDU && negative != 0)
3314a238c70SJohn Marino || (rnd_mode == MPFR_RNDD && negative == 0))
3324a238c70SJohn Marino return get_decimal64_max (negative);
3334a238c70SJohn Marino else
3344a238c70SJohn Marino return get_decimal64_inf (negative);
3354a238c70SJohn Marino }
3364a238c70SJohn Marino else
3374a238c70SJohn Marino {
3384a238c70SJohn Marino /* we need to store the sign (1), the mantissa (16), and the terminating
3394a238c70SJohn Marino character, thus we need at least 18 characters in s */
3404a238c70SJohn Marino char s[23];
3414a238c70SJohn Marino mpfr_get_str (s, &e, 10, 16, src, rnd_mode);
3424a238c70SJohn Marino /* the smallest normal number is 1.000...000E-383,
3434a238c70SJohn Marino which corresponds to s=[0.]1000...000 and e=-382 */
3444a238c70SJohn Marino if (e < -382)
3454a238c70SJohn Marino {
3464a238c70SJohn Marino /* the smallest subnormal number is 0.000...001E-383 = 1E-398,
3474a238c70SJohn Marino which corresponds to s=[0.]1000...000 and e=-397 */
3484a238c70SJohn Marino if (e < -397)
3494a238c70SJohn Marino {
350*ab6d115fSJohn Marino if (rnd_mode == MPFR_RNDN && e == -398)
351*ab6d115fSJohn Marino {
352*ab6d115fSJohn Marino /* If 0.5E-398 < |src| < 1E-398 (smallest subnormal),
353*ab6d115fSJohn Marino src should round to +/- 1E-398 in MPFR_RNDN. */
354*ab6d115fSJohn Marino mpfr_get_str (s, &e, 10, 1, src, MPFR_RNDA);
355*ab6d115fSJohn Marino return e == -398 && s[negative] <= '5' ?
356*ab6d115fSJohn Marino get_decimal64_zero (negative) :
357*ab6d115fSJohn Marino get_decimal64_min (negative);
358*ab6d115fSJohn Marino }
3594a238c70SJohn Marino if (rnd_mode == MPFR_RNDZ || rnd_mode == MPFR_RNDN
3604a238c70SJohn Marino || (rnd_mode == MPFR_RNDD && negative == 0)
3614a238c70SJohn Marino || (rnd_mode == MPFR_RNDU && negative != 0))
3624a238c70SJohn Marino return get_decimal64_zero (negative);
3634a238c70SJohn Marino else /* return the smallest non-zero number */
3644a238c70SJohn Marino return get_decimal64_min (negative);
3654a238c70SJohn Marino }
3664a238c70SJohn Marino else
3674a238c70SJohn Marino {
3684a238c70SJohn Marino mpfr_exp_t e2;
3694a238c70SJohn Marino long digits = 16 - (-382 - e);
3704a238c70SJohn Marino /* if e = -397 then 16 - (-382 - e) = 1 */
3714a238c70SJohn Marino mpfr_get_str (s, &e2, 10, digits, src, rnd_mode);
3724a238c70SJohn Marino /* Warning: we can have e2 = e + 1 here, when rounding to
3734a238c70SJohn Marino nearest or away from zero. */
3744a238c70SJohn Marino s[negative + digits] = 'E';
3754a238c70SJohn Marino sprintf (s + negative + digits + 1, "%ld",
3764a238c70SJohn Marino (long int)e2 - digits);
3774a238c70SJohn Marino return string_to_Decimal64 (s);
3784a238c70SJohn Marino }
3794a238c70SJohn Marino }
3804a238c70SJohn Marino /* the largest number is 9.999...999E+384,
3814a238c70SJohn Marino which corresponds to s=[0.]9999...999 and e=385 */
3824a238c70SJohn Marino else if (e > 385)
3834a238c70SJohn Marino {
384*ab6d115fSJohn Marino if (rnd_mode == MPFR_RNDZ
385*ab6d115fSJohn Marino || (rnd_mode == MPFR_RNDU && negative != 0)
3864a238c70SJohn Marino || (rnd_mode == MPFR_RNDD && negative == 0))
3874a238c70SJohn Marino return get_decimal64_max (negative);
3884a238c70SJohn Marino else
3894a238c70SJohn Marino return get_decimal64_inf (negative);
3904a238c70SJohn Marino }
3914a238c70SJohn Marino else /* -382 <= e <= 385 */
3924a238c70SJohn Marino {
3934a238c70SJohn Marino s[16 + negative] = 'E';
3944a238c70SJohn Marino sprintf (s + 17 + negative, "%ld", (long int)e - 16);
3954a238c70SJohn Marino return string_to_Decimal64 (s);
3964a238c70SJohn Marino }
3974a238c70SJohn Marino }
3984a238c70SJohn Marino }
3994a238c70SJohn Marino
4004a238c70SJohn Marino #endif /* MPFR_WANT_DECIMAL_FLOATS */
401