xref: /netbsd-src/external/lgpl3/mpfr/dist/src/set_d64.c (revision ba125506a622fe649968631a56eba5d42ff57863)
1 /* mpfr_set_decimal64 -- convert an IEEE 754-2008 decimal64 float to
2                          a multiple precision floating-point number
3 
4 See https://gcc.gnu.org/legacy-ml/gcc/2006-06/msg00691.html,
5 https://gcc.gnu.org/onlinedocs/gcc/Decimal-Float.html,
6 and TR 24732 <https://www.open-std.org/jtc1/sc22/wg14/www/projects#24732>.
7 
8 Copyright 2006-2023 Free Software Foundation, Inc.
9 Contributed by the AriC and Caramba projects, INRIA.
10 
11 This file is part of the GNU MPFR Library.
12 
13 The GNU MPFR Library is free software; you can redistribute it and/or modify
14 it under the terms of the GNU Lesser General Public License as published by
15 the Free Software Foundation; either version 3 of the License, or (at your
16 option) any later version.
17 
18 The GNU MPFR Library is distributed in the hope that it will be useful, but
19 WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
20 or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
21 License for more details.
22 
23 You should have received a copy of the GNU Lesser General Public License
24 along with the GNU MPFR Library; see the file COPYING.LESSER.  If not, see
25 https://www.gnu.org/licenses/ or write to the Free Software Foundation, Inc.,
26 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. */
27 
28 #define MPFR_NEED_LONGLONG_H
29 #include "mpfr-impl.h"
30 
31 #ifdef MPFR_WANT_DECIMAL_FLOATS
32 
33 #ifdef DECIMAL_DPD_FORMAT
34   /* conversion 10-bits to 3 digits */
35 static unsigned int T[1024] = {
36   0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 80, 81, 800, 801, 880, 881, 10, 11, 12, 13,
37   14, 15, 16, 17, 18, 19, 90, 91, 810, 811, 890, 891, 20, 21, 22, 23, 24, 25,
38   26, 27, 28, 29, 82, 83, 820, 821, 808, 809, 30, 31, 32, 33, 34, 35, 36, 37,
39   38, 39, 92, 93, 830, 831, 818, 819, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49,
40   84, 85, 840, 841, 88, 89, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 94, 95,
41   850, 851, 98, 99, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 86, 87, 860, 861,
42   888, 889, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 96, 97, 870, 871, 898,
43   899, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 180, 181, 900, 901,
44   980, 981, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 190, 191, 910,
45   911, 990, 991, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 182, 183,
46   920, 921, 908, 909, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 192,
47   193, 930, 931, 918, 919, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149,
48   184, 185, 940, 941, 188, 189, 150, 151, 152, 153, 154, 155, 156, 157, 158,
49   159, 194, 195, 950, 951, 198, 199, 160, 161, 162, 163, 164, 165, 166, 167,
50   168, 169, 186, 187, 960, 961, 988, 989, 170, 171, 172, 173, 174, 175, 176,
51   177, 178, 179, 196, 197, 970, 971, 998, 999, 200, 201, 202, 203, 204, 205,
52   206, 207, 208, 209, 280, 281, 802, 803, 882, 883, 210, 211, 212, 213, 214,
53   215, 216, 217, 218, 219, 290, 291, 812, 813, 892, 893, 220, 221, 222, 223,
54   224, 225, 226, 227, 228, 229, 282, 283, 822, 823, 828, 829, 230, 231, 232,
55   233, 234, 235, 236, 237, 238, 239, 292, 293, 832, 833, 838, 839, 240, 241,
56   242, 243, 244, 245, 246, 247, 248, 249, 284, 285, 842, 843, 288, 289, 250,
57   251, 252, 253, 254, 255, 256, 257, 258, 259, 294, 295, 852, 853, 298, 299,
58   260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 286, 287, 862, 863, 888,
59   889, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 296, 297, 872, 873,
60   898, 899, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 380, 381, 902,
61   903, 982, 983, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 390, 391,
62   912, 913, 992, 993, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 382,
63   383, 922, 923, 928, 929, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339,
64   392, 393, 932, 933, 938, 939, 340, 341, 342, 343, 344, 345, 346, 347, 348,
65   349, 384, 385, 942, 943, 388, 389, 350, 351, 352, 353, 354, 355, 356, 357,
66   358, 359, 394, 395, 952, 953, 398, 399, 360, 361, 362, 363, 364, 365, 366,
67   367, 368, 369, 386, 387, 962, 963, 988, 989, 370, 371, 372, 373, 374, 375,
68   376, 377, 378, 379, 396, 397, 972, 973, 998, 999, 400, 401, 402, 403, 404,
69   405, 406, 407, 408, 409, 480, 481, 804, 805, 884, 885, 410, 411, 412, 413,
70   414, 415, 416, 417, 418, 419, 490, 491, 814, 815, 894, 895, 420, 421, 422,
71   423, 424, 425, 426, 427, 428, 429, 482, 483, 824, 825, 848, 849, 430, 431,
72   432, 433, 434, 435, 436, 437, 438, 439, 492, 493, 834, 835, 858, 859, 440,
73   441, 442, 443, 444, 445, 446, 447, 448, 449, 484, 485, 844, 845, 488, 489,
74   450, 451, 452, 453, 454, 455, 456, 457, 458, 459, 494, 495, 854, 855, 498,
75   499, 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, 486, 487, 864, 865,
76   888, 889, 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, 496, 497, 874,
77   875, 898, 899, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 580, 581,
78   904, 905, 984, 985, 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, 590,
79   591, 914, 915, 994, 995, 520, 521, 522, 523, 524, 525, 526, 527, 528, 529,
80   582, 583, 924, 925, 948, 949, 530, 531, 532, 533, 534, 535, 536, 537, 538,
81   539, 592, 593, 934, 935, 958, 959, 540, 541, 542, 543, 544, 545, 546, 547,
82   548, 549, 584, 585, 944, 945, 588, 589, 550, 551, 552, 553, 554, 555, 556,
83   557, 558, 559, 594, 595, 954, 955, 598, 599, 560, 561, 562, 563, 564, 565,
84   566, 567, 568, 569, 586, 587, 964, 965, 988, 989, 570, 571, 572, 573, 574,
85   575, 576, 577, 578, 579, 596, 597, 974, 975, 998, 999, 600, 601, 602, 603,
86   604, 605, 606, 607, 608, 609, 680, 681, 806, 807, 886, 887, 610, 611, 612,
87   613, 614, 615, 616, 617, 618, 619, 690, 691, 816, 817, 896, 897, 620, 621,
88   622, 623, 624, 625, 626, 627, 628, 629, 682, 683, 826, 827, 868, 869, 630,
89   631, 632, 633, 634, 635, 636, 637, 638, 639, 692, 693, 836, 837, 878, 879,
90   640, 641, 642, 643, 644, 645, 646, 647, 648, 649, 684, 685, 846, 847, 688,
91   689, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 694, 695, 856, 857,
92   698, 699, 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, 686, 687, 866,
93   867, 888, 889, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, 696, 697,
94   876, 877, 898, 899, 700, 701, 702, 703, 704, 705, 706, 707, 708, 709, 780,
95   781, 906, 907, 986, 987, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719,
96   790, 791, 916, 917, 996, 997, 720, 721, 722, 723, 724, 725, 726, 727, 728,
97   729, 782, 783, 926, 927, 968, 969, 730, 731, 732, 733, 734, 735, 736, 737,
98   738, 739, 792, 793, 936, 937, 978, 979, 740, 741, 742, 743, 744, 745, 746,
99   747, 748, 749, 784, 785, 946, 947, 788, 789, 750, 751, 752, 753, 754, 755,
100   756, 757, 758, 759, 794, 795, 956, 957, 798, 799, 760, 761, 762, 763, 764,
101   765, 766, 767, 768, 769, 786, 787, 966, 967, 988, 989, 770, 771, 772, 773,
102   774, 775, 776, 777, 778, 779, 796, 797, 976, 977, 998, 999 };
103 #endif
104 
105 #if _MPFR_IEEE_FLOATS && !defined(DECIMAL_GENERIC_CODE)
106 
107 /* Convert d to a decimal string (one-to-one correspondence, no rounding).
108    The string s needs to have at least 25 characters (with the final '\0'):
109    * 1 for the sign '-'
110    * 2 for the leading '0.'
111    * 16 for the significand
112    * 5 for the exponent (for example 'E-100')
113    * 1 for the final '\0'
114  */
115 static void
decimal64_to_string(char * s,_Decimal64 d)116 decimal64_to_string (char *s, _Decimal64 d)
117 {
118   union mpfr_ieee_double_extract x;
119   union ieee_double_decimal64 y;
120   char *t;
121   unsigned int Gh; /* most 5 significant bits from combination field */
122   int exp; /* exponent */
123   unsigned int i;
124 
125 #ifdef DECIMAL_DPD_FORMAT
126   unsigned int d0, d1, d2, d3, d4, d5;
127 #else /* BID */
128 #if GMP_NUMB_BITS >= 64
129   mp_limb_t rp[2];
130 #else
131   unsigned long rp[2]; /* rp[0] and rp[1] should contain at least 32 bits */
132 #endif
133 #define NLIMBS (64 / GMP_NUMB_BITS)
134   mp_limb_t sp[NLIMBS];
135   mp_size_t sn;
136 #endif
137 
138   /* end of declarations */
139 
140   /* Memory representation of the _Decimal64 argument. */
141   MPFR_LOG_MSG (("d = { %02X, %02X, %02X, %02X, %02X, %02X, %02X, %02X }\n",
142                  ((unsigned char *) &d)[0],
143                  ((unsigned char *) &d)[1],
144                  ((unsigned char *) &d)[2],
145                  ((unsigned char *) &d)[3],
146                  ((unsigned char *) &d)[4],
147                  ((unsigned char *) &d)[5],
148                  ((unsigned char *) &d)[6],
149                  ((unsigned char *) &d)[7]));
150 
151   /* now convert BID or DPD to string */
152   y.d64 = d;
153   x.d = y.d;
154   MPFR_LOG_MSG (("x = { .sig = %u, .exp = %u, "
155                  ".manh = 0x%05lX = %lu, .manl = 0x%08lX = %lu }\n",
156                  (unsigned int) x.s.sig, (unsigned int) x.s.exp,
157                  (unsigned long) x.s.manh, (unsigned long) x.s.manh,
158                  (unsigned long) x.s.manl, (unsigned long) x.s.manl));
159   Gh = x.s.exp >> 6;
160   if (Gh == 31)
161     {
162       sprintf (s, "NaN");
163       return;
164     }
165   else if (Gh == 30)
166     {
167       if (x.s.sig == 0)
168         sprintf (s, "Inf");
169       else
170         sprintf (s, "-Inf");
171       return;
172     }
173   t = s;
174   if (x.s.sig)
175     *t++ = '-';
176 
177   /* both the decimal64 DPD and BID encodings consist of:
178    * a sign bit of 1 bit
179    * a combination field of 13=5+8 bits
180    * a trailing significand field of 50 bits
181    */
182 #ifdef DECIMAL_DPD_FORMAT
183   /* the most significant 5 bits of the combination field give the first digit
184      of the significand, and leading bits of the biased exponent (0, 1, 2). */
185   if (Gh < 24)
186     {
187       exp = (x.s.exp >> 1) & 768;
188       d0 = Gh & 7; /* first digit is in 0..7 */
189     }
190   else
191     {
192       exp = (x.s.exp & 384) << 1;
193       d0 = 8 | (Gh & 1); /* first digit is 8 or 9 */
194     }
195   exp |= (x.s.exp & 63) << 2;
196   exp |= x.s.manh >> 18;
197   d1 = (x.s.manh >> 8) & 1023;
198   d2 = ((x.s.manh << 2) | (x.s.manl >> 30)) & 1023;
199   d3 = (x.s.manl >> 20) & 1023;
200   d4 = (x.s.manl >> 10) & 1023;
201   d5 = x.s.manl & 1023;
202   sprintf (t, "%1u%3u%3u%3u%3u%3u", d0, T[d1], T[d2], T[d3], T[d4], T[d5]);
203   /* Warning: some characters may be blank */
204   for (i = 0; i < 16; i++)
205     if (t[i] == ' ')
206       t[i] = '0';
207   t += 16;
208 #else /* BID */
209   /* IEEE 754-2008 specifies that if the decoded significand exceeds the
210      maximum, i.e. here if it is >= 10^16, then the value is zero. */
211   if (Gh < 24)
212     {
213       /* the biased exponent E is formed from G[0] to G[9] and the
214          significand from bits G[10] through the end of the decoding */
215       exp = x.s.exp >> 1;
216       /* manh has 20 bits, manl has 32 bits */
217       rp[1] = ((x.s.exp & 1) << 20) | x.s.manh;
218       rp[0] = x.s.manl;
219     }
220   else
221     {
222       /* the biased exponent is formed from G[2] to G[11] */
223       exp = (x.s.exp & 511) << 1;
224       rp[1] = x.s.manh;
225       rp[0] = x.s.manl;
226       exp |= rp[1] >> 19;
227       rp[1] &= 524287; /* 2^19-1: cancel G[11] */
228       rp[1] |= 2097152; /* add 2^21 */
229     }
230   /* now convert {rp, 2} to {sp, NLIMBS} */
231 #if GMP_NUMB_BITS >= 64
232   sp[0] = MPFR_LIMB(rp[0]) | MPFR_LIMB_LSHIFT(rp[1],32);
233 #elif GMP_NUMB_BITS == 32
234   sp[0] = rp[0];
235   sp[1] = rp[1];
236 #elif GMP_NUMB_BITS == 16
237   sp[0] = MPFR_LIMB(rp[0]);
238   sp[1] = MPFR_LIMB(rp[0] >> 16);
239   sp[2] = MPFR_LIMB(rp[1]);
240   sp[3] = MPFR_LIMB(rp[1] >> 16);
241 #elif GMP_NUMB_BITS == 8
242   sp[0] = MPFR_LIMB(rp[0]);
243   sp[1] = MPFR_LIMB(rp[0] >> 8);
244   sp[2] = MPFR_LIMB(rp[0] >> 16);
245   sp[3] = MPFR_LIMB(rp[0] >> 24);
246   sp[4] = MPFR_LIMB(rp[1]);
247   sp[5] = MPFR_LIMB(rp[1] >> 8);
248   sp[6] = MPFR_LIMB(rp[1] >> 16);
249   sp[7] = MPFR_LIMB(rp[1] >> 24);
250 #else
251 #error "GMP_NUMB_BITS should be 8, 16, 32, or >= 64"
252 #endif
253   sn = NLIMBS;
254   while (sn > 0 && sp[sn - 1] == 0)
255     sn --;
256   if (sn == 0)
257     {
258     zero:
259       *t = 0;
260       i = 1;
261     }
262   else
263     {
264       i = mpn_get_str ((unsigned char*) t, 10, sp, sn);
265       if (i > 16) /* non-canonical encoding: return zero */
266         goto zero;
267     }
268   /* convert the values from mpn_get_str (0, 1, ..., 9) to digits: */
269   while (i-- > 0)
270     *t++ += '0';
271 #endif /* DPD or BID */
272 
273   exp -= 398; /* unbiased exponent: -398 = emin - (p-1) where
274                  emin = 1-emax = 1-384 = -383 and p=16 */
275   sprintf (t, "E%d", exp);
276 }
277 
278 #else  /* portable version */
279 
280 #ifndef DEC64_MAX
281 # define DEC64_MAX 9.999999999999999E384dd
282 #endif
283 
284 static void
decimal64_to_string(char * s,_Decimal64 d)285 decimal64_to_string (char *s, _Decimal64 d)
286 {
287   int sign = 0, n;
288   int exp = 0;
289 
290   if (MPFR_UNLIKELY (DOUBLE_ISNAN (d))) /* NaN */
291     {
292       /* we don't propagate the sign bit */
293       sprintf (s, "NaN"); /* sprintf puts a final '\0' */
294       return;
295     }
296   else if (MPFR_UNLIKELY (d > DEC64_MAX)) /* +Inf */
297     {
298       sprintf (s, "Inf");
299       return;
300     }
301   else if (MPFR_UNLIKELY (d < -DEC64_MAX)) /* -Inf */
302     {
303       sprintf (s, "-Inf");
304       return;
305     }
306 
307   /* now d is neither NaN nor +Inf nor -Inf */
308 
309   if (d < (_Decimal64) 0.0)
310     {
311       sign = 1;
312       d = -d;
313     }
314   else if (d == (_Decimal64) -0.0)
315     { /* Warning: the comparison d == -0.0 returns true for d = 0.0 too,
316          copy code from set_d.c here. We first compare to the +0.0 bitstring,
317          in case +0.0 and -0.0 are represented identically. */
318       double dd = (double) d, poszero = +0.0, negzero = DBL_NEG_ZERO;
319       if (memcmp (&dd, &poszero, sizeof(double)) != 0 &&
320           memcmp (&dd, &negzero, sizeof(double)) == 0)
321         {
322           sign = 1;
323           d = -d;
324         }
325     }
326 
327   /* now normalize d in [0.1, 1[ */
328   if (d >= (_Decimal64) 1.0)
329     {
330       _Decimal64 ten16 = (double) 1e16; /* 10^16 is exactly representable
331                                            in binary64 */
332       _Decimal64 ten32 = ten16 * ten16;
333       _Decimal64 ten64 = ten32 * ten32;
334       _Decimal64 ten128 = ten64 * ten64;
335       _Decimal64 ten256 = ten128 * ten128;
336 
337       if (d >= ten256)
338         {
339           d /= ten256;
340           exp += 256;
341         }
342       if (d >= ten128)
343         {
344           d /= ten128;
345           exp += 128;
346         }
347       if (d >= ten64)
348         {
349           d /= ten64;
350           exp += 64;
351         }
352       if (d >= ten32)
353         {
354           d /= ten32;
355           exp += 32;
356         }
357       if (d >= (_Decimal64) 10000000000000000.0)
358         {
359           d /= (_Decimal64) 10000000000000000.0;
360           exp += 16;
361         }
362       if (d >= (_Decimal64) 100000000.0)
363         {
364           d /= (_Decimal64) 100000000.0;
365           exp += 8;
366         }
367       if (d >= (_Decimal64) 10000.0)
368         {
369           d /= (_Decimal64) 10000.0;
370           exp += 4;
371         }
372       if (d >= (_Decimal64) 100.0)
373         {
374           d /= (_Decimal64) 100.0;
375           exp += 2;
376         }
377       if (d >= (_Decimal64) 10.0)
378         {
379           d /= (_Decimal64) 10.0;
380           exp += 1;
381         }
382       if (d >= (_Decimal64) 1.0)
383         {
384           d /= (_Decimal64) 10.0;
385           exp += 1;
386         }
387     }
388   else /* d < 1.0 */
389     {
390       _Decimal64 ten16, ten32, ten64, ten128, ten256;
391 
392       ten16 = (double) 1e16; /* 10^16 is exactly representable in binary64 */
393       ten16 = (_Decimal64) 1.0 / ten16; /* 10^(-16), exact */
394       ten32 = ten16 * ten16;
395       ten64 = ten32 * ten32;
396       ten128 = ten64 * ten64;
397       ten256 = ten128 * ten128;
398 
399       if (d < ten256)
400         {
401           d /= ten256;
402           exp -= 256;
403         }
404       if (d < ten128)
405         {
406           d /= ten128;
407           exp -= 128;
408         }
409       if (d < ten64)
410         {
411           d /= ten64;
412           exp -= 64;
413         }
414       if (d < ten32)
415         {
416           d /= ten32;
417           exp -= 32;
418         }
419       /* the double constant 0.0000000000000001 is 2028240960365167/2^104,
420          which should be rounded to 1e-16 in _Decimal64 */
421       if (d < (_Decimal64) 0.0000000000000001)
422         {
423           d *= (_Decimal64) 10000000000000000.0;
424           exp -= 16;
425         }
426       /* the double constant 0.00000001 is 3022314549036573/2^78,
427          which should be rounded to 1e-8 in _Decimal64 */
428       if (d < (_Decimal64) 0.00000001)
429         {
430           d *= (_Decimal64) 100000000.0;
431           exp -= 8;
432         }
433       /* the double constant 0.0001 is 7378697629483821/2^66,
434          which should be rounded to 1e-4 in _Decimal64 */
435       if (d < (_Decimal64) 0.0001)
436         {
437           d *= (_Decimal64) 10000.0;
438           exp -= 4;
439         }
440       /* the double constant 0.01 is 5764607523034235/2^59,
441          which should be rounded to 1e-2 in _Decimal64 */
442       if (d < (_Decimal64) 0.01)
443         {
444           d *= (_Decimal64) 100.0;
445           exp -= 2;
446         }
447       /* the double constant 0.1 is 3602879701896397/2^55,
448          which should be rounded to 1e-1 in _Decimal64 */
449       if (d < (_Decimal64) 0.1)
450         {
451           d *= (_Decimal64) 10.0;
452           exp -= 1;
453         }
454     }
455 
456   /* now 0.1 <= d < 1 */
457   if (sign == 1)
458     *s++ = '-';
459   *s++ = '0';
460   *s++ = '.';
461   for (n = 0; n < 16; n++)
462     {
463       double e;
464       int r;
465 
466       d *= (_Decimal64) 10.0;
467       e = (double) d;
468       r = (int) e;
469       *s++ = '0' + r;
470       d -= (_Decimal64) r;
471     }
472   MPFR_ASSERTN(d == (_Decimal64) 0.0);
473   if (exp != 0)
474     sprintf (s, "E%d", exp); /* adds a final '\0' */
475   else
476     *s = '\0';
477 }
478 
479 #endif  /* definition of decimal64_to_string (DPD, BID, or portable) */
480 
481 /* the IEEE754-2008 decimal64 format has 16 digits, with emax=384,
482    emin=1-emax=-383 */
483 int
mpfr_set_decimal64(mpfr_ptr r,_Decimal64 d,mpfr_rnd_t rnd_mode)484 mpfr_set_decimal64 (mpfr_ptr r, _Decimal64 d, mpfr_rnd_t rnd_mode)
485 {
486   char s[25]; /* need 1 character for sign,
487                       2 characters for '0.'
488                      16 characters for significand,
489                       1 character for exponent 'E',
490                       4 characters for exponent (including sign),
491                       1 character for terminating \0. */
492 
493   decimal64_to_string (s, d);
494   MPFR_LOG_MSG (("string: %s\n", s));
495   return mpfr_strtofr (r, s, NULL, 10, rnd_mode);
496 }
497 
498 #endif /* MPFR_WANT_DECIMAL_FLOATS */
499