1 /* Copyright (C) 2007-2021 Free Software Foundation, Inc.
2 
3 This file is part of GCC.
4 
5 GCC is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free
7 Software Foundation; either version 3, or (at your option) any later
8 version.
9 
10 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
11 WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13 for more details.
14 
15 Under Section 7 of GPL version 3, you are granted additional
16 permissions described in the GCC Runtime Library Exception, version
17 3.1, as published by the Free Software Foundation.
18 
19 You should have received a copy of the GNU General Public License and
20 a copy of the GCC Runtime Library Exception along with this program;
21 see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
22 <http://www.gnu.org/licenses/>.  */
23 
24 /*****************************************************************************
25  *    BID128_to_string
26  ****************************************************************************/
27 
28 #define BID_128RES
29 #include <stdio.h>
30 #include "bid_internal.h"
31 #include "bid128_2_str.h"
32 #include "bid128_2_str_macros.h"
33 
34 extern int bid128_coeff_2_string (UINT64 X_hi, UINT64 X_lo,
35 				  char *char_ptr);
36 
37 #if DECIMAL_CALL_BY_REFERENCE
38 
39 void
bid128_to_string(char * str,UINT128 * px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM)40 bid128_to_string (char *str,
41 		  UINT128 *
42 		  px _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
43 		  _EXC_INFO_PARAM) {
44   UINT128 x;
45 #else
46 
47 void
48 bid128_to_string (char *str, UINT128 x
49     _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
50 #endif
51   UINT64 x_sign;
52   UINT64 x_exp;
53   int exp; 	// unbiased exponent
54   // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
55   int ind;
56   UINT128 C1;
57   unsigned int k = 0; // pointer in the string
58   unsigned int d0, d123;
59   UINT64 HI_18Dig, LO_18Dig, Tmp;
60   UINT32 MiDi[12], *ptr;
61   char *c_ptr_start, *c_ptr;
62   int midi_ind, k_lcv, len;
63 
64 #if DECIMAL_CALL_BY_REFERENCE
65   x = *px;
66 #endif
67 
68   BID_SWAP128(x);
69   // check for NaN or Infinity
70   if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
71     // x is special
72     if ((x.w[1] & MASK_NAN) == MASK_NAN) { // x is NAN
73       if ((x.w[1] & MASK_SNAN) == MASK_SNAN) { // x is SNAN
74 	// set invalid flag
75     str[0] = ((SINT64)x.w[1]<0)? '-':'+';
76 	str[1] = 'S';
77 	str[2] = 'N';
78 	str[3] = 'a';
79 	str[4] = 'N';
80 	str[5] = '\0';
81       } else { // x is QNaN
82     str[0] = ((SINT64)x.w[1]<0)? '-':'+';
83 	str[1] = 'Q';
84 	str[2] = 'N';
85 	str[3] = 'a';
86 	str[4] = 'N';
87 	str[5] = '\0';
88       }
89     } else { // x is not a NaN, so it must be infinity
90       if ((x.w[1] & MASK_SIGN) == 0x0ull) { // x is +inf
91 	str[0] = '+';
92 	str[1] = 'I';
93 	str[2] = 'n';
94 	str[3] = 'f';
95 	str[4] = '\0';
96       } else { // x is -inf
97 	str[0] = '-';
98 	str[1] = 'I';
99 	str[2] = 'n';
100 	str[3] = 'f';
101 	str[4] = '\0';
102       }
103     }
104     return;
105   } else if (((x.w[1] & MASK_COEFF) == 0x0ull) && (x.w[0] == 0x0ull)) {
106     // x is 0
107     len = 0;
108 
109     //determine if +/-
110     if (x.w[1] & MASK_SIGN)
111       str[len++] = '-';
112     else
113       str[len++] = '+';
114     str[len++] = '0';
115     str[len++] = 'E';
116 
117     // extract the exponent and print
118     exp = (int) (((x.w[1] & MASK_EXP) >> 49) - 6176);
119 	if(exp > (((0x5ffe)>>1) - (6176))) {
120 		exp = (int) ((((x.w[1]<<2) & MASK_EXP) >> 49) - 6176);
121 	}
122     if (exp >= 0) {
123       str[len++] = '+';
124       len += sprintf (str + len, "%u", exp);// should not use sprintf (should
125       // use sophisticated algorithm, since we know range of exp is limited)
126       str[len++] = '\0';
127     } else {
128       len += sprintf (str + len, "%d", exp);// should not use sprintf (should
129       // use sophisticated algorithm, since we know range of exp is limited)
130       str[len++] = '\0';
131     }
132     return;
133   } else { // x is not special and is not zero
134     // unpack x
135     x_sign = x.w[1] & MASK_SIGN;// 0 for positive, MASK_SIGN for negative
136     x_exp = x.w[1] & MASK_EXP;// biased and shifted left 49 bit positions
137     if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)
138        x_exp = (x.w[1]<<2) & MASK_EXP;// biased and shifted left 49 bit positions
139     C1.w[1] = x.w[1] & MASK_COEFF;
140     C1.w[0] = x.w[0];
141     exp = (x_exp >> 49) - 6176;
142 
143     // determine sign's representation as a char
144     if (x_sign)
145       str[k++] = '-';// negative number
146     else
147       str[k++] = '+';// positive number
148 
149     // determine coefficient's representation as a decimal string
150 
151     // if zero or non-canonical, set coefficient to '0'
152     if ((C1.w[1] > 0x0001ed09bead87c0ull) ||
153         (C1.w[1] == 0x0001ed09bead87c0ull &&
154         (C1.w[0] > 0x378d8e63ffffffffull)) ||
155         ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) ||
156         ((C1.w[1] == 0) && (C1.w[0] == 0))) {
157       str[k++] = '0';
158     } else {
159       /* ****************************************************
160          This takes a bid coefficient in C1.w[1],C1.w[0]
161          and put the converted character sequence at location
162          starting at &(str[k]). The function returns the number
163          of MiDi returned. Note that the character sequence
164          does not have leading zeros EXCEPT when the input is of
165          zero value. It will then output 1 character '0'
166          The algorithm essentailly tries first to get a sequence of
167          Millenial Digits "MiDi" and then uses table lookup to get the
168          character strings of these MiDis.
169          **************************************************** */
170       /* Algorithm first decompose possibly 34 digits in hi and lo
171          18 digits. (The high can have at most 16 digits). It then
172          uses macro that handle 18 digit portions.
173          The first step is to get hi and lo such that
174          2^(64) C1.w[1] + C1.w[0] = hi * 10^18  + lo,   0 <= lo < 10^18.
175          We use a table lookup method to obtain the hi and lo 18 digits.
176          [C1.w[1],C1.w[0]] = c_8 2^(107) + c_7 2^(101) + ... + c_0 2^(59) + d
177          where 0 <= d < 2^59 and each c_j has 6 bits. Because d fits in
178          18 digits,  we set hi = 0, and lo = d to begin with.
179          We then retrieve from a table, for j = 0, 1, ..., 8
180          that gives us A and B where c_j 2^(59+6j) = A * 10^18 + B.
181          hi += A ; lo += B; After each accumulation into lo, we normalize
182          immediately. So at the end, we have the decomposition as we need. */
183 
184       Tmp = C1.w[0] >> 59;
185       LO_18Dig = (C1.w[0] << 5) >> 5;
186       Tmp += (C1.w[1] << 5);
187       HI_18Dig = 0;
188       k_lcv = 0;
189       // Tmp = {C1.w[1]{49:0}, C1.w[0]{63:59}}
190       // Lo_18Dig = {C1.w[0]{58:0}}
191 
192       while (Tmp) {
193 	midi_ind = (int) (Tmp & 0x000000000000003FLL);
194 	midi_ind <<= 1;
195 	Tmp >>= 6;
196 	HI_18Dig += mod10_18_tbl[k_lcv][midi_ind++];
197 	LO_18Dig += mod10_18_tbl[k_lcv++][midi_ind];
198 	__L0_Normalize_10to18 (HI_18Dig, LO_18Dig);
199       }
200       ptr = MiDi;
201       if (HI_18Dig == 0LL) {
202 	__L1_Split_MiDi_6_Lead (LO_18Dig, ptr);
203       } else {
204 	__L1_Split_MiDi_6_Lead (HI_18Dig, ptr);
205 	__L1_Split_MiDi_6 (LO_18Dig, ptr);
206       }
207       len = ptr - MiDi;
208       c_ptr_start = &(str[k]);
209       c_ptr = c_ptr_start;
210 
211       /* now convert the MiDi into character strings */
212       __L0_MiDi2Str_Lead (MiDi[0], c_ptr);
213       for (k_lcv = 1; k_lcv < len; k_lcv++) {
214 	__L0_MiDi2Str (MiDi[k_lcv], c_ptr);
215       }
216       k = k + (c_ptr - c_ptr_start);
217     }
218 
219     // print E and sign of exponent
220     str[k++] = 'E';
221     if (exp < 0) {
222       exp = -exp;
223       str[k++] = '-';
224     } else {
225       str[k++] = '+';
226     }
227 
228     // determine exponent's representation as a decimal string
229     // d0 = exp / 1000;
230     // Use Property 1
231     d0 = (exp * 0x418a) >> 24;// 0x418a * 2^-24 = (10^(-3))RP,15
232     d123 = exp - 1000 * d0;
233 
234     if (d0) { // 1000 <= exp <= 6144 => 4 digits to return
235       str[k++] = d0 + 0x30;// ASCII for decimal digit d0
236       ind = 3 * d123;
237       str[k++] = char_table3[ind];
238       str[k++] = char_table3[ind + 1];
239       str[k++] = char_table3[ind + 2];
240     } else { // 0 <= exp <= 999 => d0 = 0
241       if (d123 < 10) { // 0 <= exp <= 9 => 1 digit to return
242 	str[k++] = d123 + 0x30;// ASCII
243       } else if (d123 < 100) { // 10 <= exp <= 99 => 2 digits to return
244 	ind = 2 * (d123 - 10);
245 	str[k++] = char_table2[ind];
246 	str[k++] = char_table2[ind + 1];
247       } else { // 100 <= exp <= 999 => 3 digits to return
248 	ind = 3 * d123;
249 	str[k++] = char_table3[ind];
250 	str[k++] = char_table3[ind + 1];
251 	str[k++] = char_table3[ind + 2];
252       }
253     }
254     str[k] = '\0';
255 
256   }
257   return;
258 
259 }
260 
261 
262 #define MAX_FORMAT_DIGITS_128   34
263 #define MAX_STRING_DIGITS_128   100
264 #define MAX_SEARCH              MAX_STRING_DIGITS_128-MAX_FORMAT_DIGITS_128-1
265 
266 
267 #if DECIMAL_CALL_BY_REFERENCE
268 
269 void
270 bid128_from_string (UINT128 * pres,
271                     char *ps _RND_MODE_PARAM _EXC_FLAGS_PARAM
272                     _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
273 #else
274 
275 UINT128
276 bid128_from_string (char *ps _RND_MODE_PARAM _EXC_FLAGS_PARAM
277                     _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
278 #endif
279   UINT128 CX, res;
280   UINT64 sign_x, coeff_high, coeff_low, coeff2, coeff_l2, carry = 0x0ull,
281     scale_high, right_radix_leading_zeros;
282   int ndigits_before, ndigits_after, ndigits_total, dec_expon, sgn_exp,
283     i, d2, rdx_pt_enc;
284   char c, buffer[MAX_STRING_DIGITS_128];
285   int save_rnd_mode;
286   int save_fpsf;
287 
288 #if DECIMAL_CALL_BY_REFERENCE
289 #if !DECIMAL_GLOBAL_ROUNDING
290   _IDEC_round rnd_mode = *prnd_mode;
291 #endif
292 #endif
293 
294   save_rnd_mode = rnd_mode; // dummy
295   save_fpsf = *pfpsf; // dummy
296 
297   right_radix_leading_zeros = rdx_pt_enc = 0;
298 
299   // if null string, return NaN
300   if (!ps) {
301     res.w[1] = 0x7c00000000000000ull;
302     res.w[0] = 0;
303     BID_RETURN (res);
304   }
305   // eliminate leading white space
306   while ((*ps == ' ') || (*ps == '\t'))
307     ps++;
308 
309   // c gets first character
310   c = *ps;
311 
312 
313   // if c is null or not equal to a (radix point, negative sign,
314   // positive sign, or number) it might be SNaN, sNaN, Infinity
315   if (!c
316       || (c != '.' && c != '-' && c != '+'
317           && ((unsigned) (c - '0') > 9))) {
318     res.w[0] = 0;
319     // Infinity?
320     if ((tolower_macro (ps[0]) == 'i' && tolower_macro (ps[1]) == 'n'
321          && tolower_macro (ps[2]) == 'f')
322         && (!ps[3]
323             || (tolower_macro (ps[3]) == 'i'
324                 && tolower_macro (ps[4]) == 'n'
325                 && tolower_macro (ps[5]) == 'i'
326                 && tolower_macro (ps[6]) == 't'
327                 && tolower_macro (ps[7]) == 'y' && !ps[8])
328         )) {
329       res.w[1] = 0x7800000000000000ull;
330       BID_RETURN (res);
331     }
332     // return sNaN
333     if (tolower_macro (ps[0]) == 's' && tolower_macro (ps[1]) == 'n' &&
334         tolower_macro (ps[2]) == 'a' && tolower_macro (ps[3]) == 'n') {
335         // case insensitive check for snan
336       res.w[1] = 0x7e00000000000000ull;
337       BID_RETURN (res);
338     } else {
339       // return qNaN
340       res.w[1] = 0x7c00000000000000ull;
341       BID_RETURN (res);
342     }
343   }
344   // if +Inf, -Inf, +Infinity, or -Infinity (case insensitive check for inf)
345   if ((tolower_macro (ps[1]) == 'i' && tolower_macro (ps[2]) == 'n' &&
346       tolower_macro (ps[3]) == 'f') && (!ps[4] ||
347       (tolower_macro (ps[4]) == 'i' && tolower_macro (ps[5]) == 'n' &&
348       tolower_macro (ps[6]) == 'i' && tolower_macro (ps[7]) == 't' &&
349       tolower_macro (ps[8]) == 'y' && !ps[9]))) { // ci check for infinity
350     res.w[0] = 0;
351 
352     if (c == '+')
353       res.w[1] = 0x7800000000000000ull;
354     else if (c == '-')
355       res.w[1] = 0xf800000000000000ull;
356     else
357       res.w[1] = 0x7c00000000000000ull;
358 
359     BID_RETURN (res);
360   }
361   // if +sNaN, +SNaN, -sNaN, or -SNaN
362   if (tolower_macro (ps[1]) == 's' && tolower_macro (ps[2]) == 'n'
363       && tolower_macro (ps[3]) == 'a' && tolower_macro (ps[4]) == 'n') {
364     res.w[0] = 0;
365     if (c == '-')
366       res.w[1] = 0xfe00000000000000ull;
367     else
368       res.w[1] = 0x7e00000000000000ull;
369     BID_RETURN (res);
370   }
371   // set up sign_x to be OR'ed with the upper word later
372   if (c == '-')
373     sign_x = 0x8000000000000000ull;
374   else
375     sign_x = 0;
376 
377   // go to next character if leading sign
378   if (c == '-' || c == '+')
379     ps++;
380 
381   c = *ps;
382 
383   // if c isn't a decimal point or a decimal digit, return NaN
384   if (c != '.' && ((unsigned) (c - '0') > 9)) {
385     res.w[1] = 0x7c00000000000000ull | sign_x;
386     res.w[0] = 0;
387     BID_RETURN (res);
388   }
389   // detect zero (and eliminate/ignore leading zeros)
390   if (*(ps) == '0') {
391 
392     // if all numbers are zeros (with possibly 1 radix point, the number is zero
393     // should catch cases such as: 000.0
394     while (*ps == '0') {
395 
396       ps++;
397 
398       // for numbers such as 0.0000000000000000000000000000000000001001,
399       // we want to count the leading zeros
400       if (rdx_pt_enc) {
401         right_radix_leading_zeros++;
402       }
403       // if this character is a radix point, make sure we haven't already
404       // encountered one
405       if (*(ps) == '.') {
406         if (rdx_pt_enc == 0) {
407           rdx_pt_enc = 1;
408           // if this is the first radix point, and the next character is NULL,
409           // we have a zero
410           if (!*(ps + 1)) {
411             res.w[1] =
412               (0x3040000000000000ull -
413                (right_radix_leading_zeros << 49)) | sign_x;
414             res.w[0] = 0;
415             BID_RETURN (res);
416           }
417           ps = ps + 1;
418         } else {
419           // if 2 radix points, return NaN
420           res.w[1] = 0x7c00000000000000ull | sign_x;
421           res.w[0] = 0;
422           BID_RETURN (res);
423         }
424       } else if (!*(ps)) {
425         //res.w[1] = 0x3040000000000000ull | sign_x;
426         res.w[1] =
427           (0x3040000000000000ull -
428            (right_radix_leading_zeros << 49)) | sign_x;
429         res.w[0] = 0;
430         BID_RETURN (res);
431       }
432     }
433   }
434 
435   c = *ps;
436 
437   // initialize local variables
438   ndigits_before = ndigits_after = ndigits_total = 0;
439   sgn_exp = 0;
440   // pstart_coefficient = ps;
441 
442   if (!rdx_pt_enc) {
443     // investigate string (before radix point)
444     while ((unsigned) (c - '0') <= 9
445            && ndigits_before < MAX_STRING_DIGITS_128) {
446       buffer[ndigits_before] = c;
447       ps++;
448       c = *ps;
449       ndigits_before++;
450     }
451 
452     ndigits_total = ndigits_before;
453     if (c == '.') {
454       ps++;
455       if ((c = *ps)) {
456 
457         // investigate string (after radix point)
458         while ((unsigned) (c - '0') <= 9
459                && ndigits_total < MAX_STRING_DIGITS_128) {
460           buffer[ndigits_total] = c;
461           ps++;
462           c = *ps;
463           ndigits_total++;
464         }
465         ndigits_after = ndigits_total - ndigits_before;
466       }
467     }
468   } else {
469     // we encountered a radix point while detecting zeros
470     //if (c = *ps){
471 
472     c = *ps;
473     ndigits_total = 0;
474     // investigate string (after radix point)
475     while ((unsigned) (c - '0') <= 9
476            && ndigits_total < MAX_STRING_DIGITS_128) {
477       buffer[ndigits_total] = c;
478       ps++;
479       c = *ps;
480       ndigits_total++;
481     }
482     ndigits_after = ndigits_total - ndigits_before;
483   }
484 
485   // get exponent
486   dec_expon = 0;
487   if (ndigits_total < MAX_STRING_DIGITS_128) {
488     if (c) {
489       if (c != 'e' && c != 'E') {
490         // return NaN
491         res.w[1] = 0x7c00000000000000ull;
492         res.w[0] = 0;
493         BID_RETURN (res);
494       }
495       ps++;
496       c = *ps;
497 
498       if (((unsigned) (c - '0') > 9)
499           && ((c != '+' && c != '-') || (unsigned) (ps[1] - '0') > 9)) {
500         // return NaN
501         res.w[1] = 0x7c00000000000000ull;
502         res.w[0] = 0;
503         BID_RETURN (res);
504       }
505 
506       if (c == '-') {
507         sgn_exp = -1;
508         ps++;
509         c = *ps;
510       } else if (c == '+') {
511         ps++;
512         c = *ps;
513       }
514 
515       dec_expon = c - '0';
516       i = 1;
517       ps++;
518       c = *ps - '0';
519       while (((unsigned) c) <= 9 && i < 7) {
520         d2 = dec_expon + dec_expon;
521         dec_expon = (d2 << 2) + d2 + c;
522         ps++;
523         c = *ps - '0';
524         i++;
525       }
526     }
527 
528     dec_expon = (dec_expon + sgn_exp) ^ sgn_exp;
529   }
530 
531 
532   if (ndigits_total <= MAX_FORMAT_DIGITS_128) {
533     dec_expon +=
534       DECIMAL_EXPONENT_BIAS_128 - ndigits_after -
535       right_radix_leading_zeros;
536     if (dec_expon < 0) {
537       res.w[1] = 0 | sign_x;
538       res.w[0] = 0;
539     }
540     if (ndigits_total == 0) {
541       CX.w[0] = 0;
542       CX.w[1] = 0;
543     } else if (ndigits_total <= 19) {
544       coeff_high = buffer[0] - '0';
545       for (i = 1; i < ndigits_total; i++) {
546         coeff2 = coeff_high + coeff_high;
547         coeff_high = (coeff2 << 2) + coeff2 + buffer[i] - '0';
548       }
549       CX.w[0] = coeff_high;
550       CX.w[1] = 0;
551     } else {
552       coeff_high = buffer[0] - '0';
553       for (i = 1; i < ndigits_total - 17; i++) {
554         coeff2 = coeff_high + coeff_high;
555         coeff_high = (coeff2 << 2) + coeff2 + buffer[i] - '0';
556       }
557       coeff_low = buffer[i] - '0';
558       i++;
559       for (; i < ndigits_total; i++) {
560         coeff_l2 = coeff_low + coeff_low;
561         coeff_low = (coeff_l2 << 2) + coeff_l2 + buffer[i] - '0';
562       }
563       // now form the coefficient as coeff_high*10^19+coeff_low+carry
564       scale_high = 100000000000000000ull;
565       __mul_64x64_to_128_fast (CX, coeff_high, scale_high);
566 
567       CX.w[0] += coeff_low;
568       if (CX.w[0] < coeff_low)
569         CX.w[1]++;
570     }
571     get_BID128 (&res, sign_x, dec_expon, CX,&rnd_mode,pfpsf);
572     BID_RETURN (res);
573   } else {
574     // simply round using the digits that were read
575 
576     dec_expon +=
577       ndigits_before + DECIMAL_EXPONENT_BIAS_128 -
578       MAX_FORMAT_DIGITS_128 - right_radix_leading_zeros;
579 
580     if (dec_expon < 0) {
581       res.w[1] = 0 | sign_x;
582       res.w[0] = 0;
583     }
584 
585     coeff_high = buffer[0] - '0';
586     for (i = 1; i < MAX_FORMAT_DIGITS_128 - 17; i++) {
587       coeff2 = coeff_high + coeff_high;
588       coeff_high = (coeff2 << 2) + coeff2 + buffer[i] - '0';
589     }
590     coeff_low = buffer[i] - '0';
591     i++;
592     for (; i < MAX_FORMAT_DIGITS_128; i++) {
593       coeff_l2 = coeff_low + coeff_low;
594       coeff_low = (coeff_l2 << 2) + coeff_l2 + buffer[i] - '0';
595     }
596 	switch(rnd_mode) {
597 	case ROUNDING_TO_NEAREST:
598     carry = ((unsigned) ('4' - buffer[i])) >> 31;
599     if ((buffer[i] == '5' && !(coeff_low & 1)) || dec_expon < 0) {
600       if (dec_expon >= 0) {
601         carry = 0;
602         i++;
603       }
604       for (; i < ndigits_total; i++) {
605         if (buffer[i] > '0') {
606           carry = 1;
607           break;
608         }
609       }
610     }
611 	break;
612 
613 	case ROUNDING_DOWN:
614 		if(sign_x)
615       for (; i < ndigits_total; i++) {
616         if (buffer[i] > '0') {
617           carry = 1;
618           break;
619         }
620       }
621 		break;
622 	case ROUNDING_UP:
623 		if(!sign_x)
624       for (; i < ndigits_total; i++) {
625         if (buffer[i] > '0') {
626           carry = 1;
627           break;
628         }
629       }
630 		break;
631 	case ROUNDING_TO_ZERO:
632 		carry=0;
633 		break;
634 	case ROUNDING_TIES_AWAY:
635     carry = ((unsigned) ('4' - buffer[i])) >> 31;
636     if (dec_expon < 0) {
637       for (; i < ndigits_total; i++) {
638         if (buffer[i] > '0') {
639           carry = 1;
640           break;
641         }
642       }
643     }
644 		break;
645 
646 
647 	}
648     // now form the coefficient as coeff_high*10^17+coeff_low+carry
649     scale_high = 100000000000000000ull;
650     if (dec_expon < 0) {
651       if (dec_expon > -MAX_FORMAT_DIGITS_128) {
652         scale_high = 1000000000000000000ull;
653         coeff_low = (coeff_low << 3) + (coeff_low << 1);
654         dec_expon--;
655       }
656       if (dec_expon == -MAX_FORMAT_DIGITS_128
657           && coeff_high > 50000000000000000ull)
658         carry = 0;
659     }
660 
661     __mul_64x64_to_128_fast (CX, coeff_high, scale_high);
662 
663     coeff_low += carry;
664     CX.w[0] += coeff_low;
665     if (CX.w[0] < coeff_low)
666       CX.w[1]++;
667 
668 
669     get_BID128(&res, sign_x, dec_expon, CX, &rnd_mode, pfpsf);
670     BID_RETURN (res);
671   }
672 }
673