(root)/
gcc-13.2.0/
libgcc/
config/
libbid/
bid128_string.c
       1  /* Copyright (C) 2007-2023 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
      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  }