On Wed, May 14, 2025 at 9:22 AM liuhongt <hongtao....@intel.com> wrote:
>
> The Intel Decimal Floating-Point Math Library is available as open-source on 
> Netlib[1].
>
> [1] https://www.netlib.org/misc/intel/
>
> Bootstrapped and regtested on x86_64-pc-linux-gnu{-m32,}.
> Ready push to trunk.
>
> libgcc/config/libbid/ChangeLog:
>
>         * bid128_string.c (MIN_DIGITS): New macro.
>         (bid128_from_string): Update function.
Will adjust changelog to

    libgcc/config/libbid/ChangeLog:

            * bid128_string.c (MIN_DIGITS): New macro.
            (bid128_from_string): Bug fix. Conversion from very long input
            string to decimal.

> ---
>  libgcc/config/libbid/bid128_string.c | 121 +++++++++++++++------------
>  1 file changed, 68 insertions(+), 53 deletions(-)
>  mode change 100644 => 100755 libgcc/config/libbid/bid128_string.c
>
> diff --git a/libgcc/config/libbid/bid128_string.c 
> b/libgcc/config/libbid/bid128_string.c
> old mode 100644
> new mode 100755
> index fce036ad5f8..49ad1795efb
> --- a/libgcc/config/libbid/bid128_string.c
> +++ b/libgcc/config/libbid/bid128_string.c
> @@ -31,6 +31,8 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  
> If not, see
>  #include "bid128_2_str.h"
>  #include "bid128_2_str_macros.h"
>
> +#define MIN_DIGITS(a,b) ((a) < (b) ? (a) : (b))
> +
>  extern int bid128_coeff_2_string (UINT64 X_hi, UINT64 X_lo,
>                                   char *char_ptr);
>
> @@ -283,6 +285,7 @@ bid128_from_string (char *ps _RND_MODE_PARAM 
> _EXC_FLAGS_PARAM
>    int ndigits_before, ndigits_after, ndigits_total, dec_expon, sgn_exp,
>      i, d2, rdx_pt_enc;
>    char c, buffer[MAX_STRING_DIGITS_128];
> +  int min_digits, sticky_bit=0;
>    int save_rnd_mode;
>    int save_fpsf;
>
> @@ -443,8 +446,10 @@ bid128_from_string (char *ps _RND_MODE_PARAM 
> _EXC_FLAGS_PARAM
>    if (!rdx_pt_enc) {
>      // investigate string (before radix point)
>      while ((unsigned) (c - '0') <= 9
> -           && ndigits_before < MAX_STRING_DIGITS_128) {
> -      buffer[ndigits_before] = c;
> +           /*&& ndigits_before < MAX_STRING_DIGITS_128*/) {
> +      if(ndigits_before < MAX_FORMAT_DIGITS_128) buffer[ndigits_before] = c;
> +      else if(ndigits_before < MAX_STRING_DIGITS_128) { 
> buffer[ndigits_before] = c; }
> +      else if(c>'0') { sticky_bit = 1; }
>        ps++;
>        c = *ps;
>        ndigits_before++;
> @@ -457,8 +462,10 @@ bid128_from_string (char *ps _RND_MODE_PARAM 
> _EXC_FLAGS_PARAM
>
>          // investigate string (after radix point)
>          while ((unsigned) (c - '0') <= 9
> -               && ndigits_total < MAX_STRING_DIGITS_128) {
> -          buffer[ndigits_total] = c;
> +               /*&& ndigits_total < MAX_STRING_DIGITS_128*/) {
> +          if(ndigits_total < MAX_FORMAT_DIGITS_128) buffer[ndigits_total] = 
> c;
> +          else if(ndigits_total < MAX_STRING_DIGITS_128) { 
> buffer[ndigits_total] = c; }
> +         else if(c>'0') { sticky_bit = 1; }
>            ps++;
>            c = *ps;
>            ndigits_total++;
> @@ -474,8 +481,10 @@ bid128_from_string (char *ps _RND_MODE_PARAM 
> _EXC_FLAGS_PARAM
>      ndigits_total = 0;
>      // investigate string (after radix point)
>      while ((unsigned) (c - '0') <= 9
> -           && ndigits_total < MAX_STRING_DIGITS_128) {
> -      buffer[ndigits_total] = c;
> +           /*&& ndigits_total < MAX_STRING_DIGITS_128*/) {
> +      if(ndigits_total < MAX_FORMAT_DIGITS_128)  buffer[ndigits_total] = c;
> +      else if(ndigits_total < MAX_STRING_DIGITS_128)  { 
> buffer[ndigits_total] = c; }
> +      else if(c>'0') { sticky_bit = 1; }
>        ps++;
>        c = *ps;
>        ndigits_total++;
> @@ -594,57 +603,63 @@ bid128_from_string (char *ps _RND_MODE_PARAM 
> _EXC_FLAGS_PARAM
>        coeff_l2 = coeff_low + coeff_low;
>        coeff_low = (coeff_l2 << 2) + coeff_l2 + buffer[i] - '0';
>      }
> -       switch(rnd_mode) {
> -       case ROUNDING_TO_NEAREST:
> -    carry = ((unsigned) ('4' - buffer[i])) >> 31;
> -    if ((buffer[i] == '5' && !(coeff_low & 1)) || dec_expon < 0) {
> -      if (dec_expon >= 0) {
> -        carry = 0;
> -        i++;
> -      }
> -      for (; i < ndigits_total; i++) {
> -        if (buffer[i] > '0') {
> -          carry = 1;
> -          break;
> -        }
> +    switch(rnd_mode) {
> +    case ROUNDING_TO_NEAREST:
> +      carry = ((unsigned) ('4' - buffer[i])) >> 31;
> +      if ((buffer[i] == '5' && !(coeff_low & 1) && !sticky_bit) || dec_expon 
> < 0) {
> +       if (dec_expon >= 0) {
> +         carry = 0;
> +         i++;
> +       }
> +        min_digits = MIN_DIGITS(ndigits_total, MAX_STRING_DIGITS_128);
> +       for (carry=sticky_bit; (!carry) && (i < min_digits); i++) {
> +         if (buffer[i] > '0') {
> +           carry = 1;
> +           break;
> +         }
> +       }
>        }
> -    }
> -       break;
> -
> -       case ROUNDING_DOWN:
> -               if(sign_x)
> -      for (; i < ndigits_total; i++) {
> -        if (buffer[i] > '0') {
> -          carry = 1;
> -          break;
> -        }
> +      break;
> +
> +    case ROUNDING_DOWN:
> +      if(sign_x) {
> +        min_digits = MIN_DIGITS(ndigits_total, MAX_STRING_DIGITS_128);
> +        for (carry=sticky_bit; (!carry) && (i < min_digits); i++) {
> +         if (buffer[i] > '0') {
> +           carry = 1;
> +           break;
> +         }
> +       }
>        }
> -               break;
> -       case ROUNDING_UP:
> -               if(!sign_x)
> -      for (; i < ndigits_total; i++) {
> -        if (buffer[i] > '0') {
> -          carry = 1;
> -          break;
> -        }
> +      break;
> +    case ROUNDING_UP:
> +      if(!sign_x) {
> +       min_digits = MIN_DIGITS(ndigits_total, MAX_STRING_DIGITS_128);
> +        for (carry=sticky_bit; (!carry) && (i < min_digits); i++) {
> +         if (buffer[i] > '0') {
> +           carry = 1;
> +           break;
> +         }
> +       }
>        }
> -               break;
> -       case ROUNDING_TO_ZERO:
> -               carry=0;
> -               break;
> -       case ROUNDING_TIES_AWAY:
> -    carry = ((unsigned) ('4' - buffer[i])) >> 31;
> -    if (dec_expon < 0) {
> -      for (; i < ndigits_total; i++) {
> -        if (buffer[i] > '0') {
> -          carry = 1;
> -          break;
> -        }
> +      break;
> +    case ROUNDING_TO_ZERO:
> +      carry=0;
> +      break;
> +    case ROUNDING_TIES_AWAY:
> +      carry = ((unsigned) ('4' - buffer[i])) >> 31;
> +      if (dec_expon < 0) {
> +        min_digits = MIN_DIGITS(ndigits_total, MAX_STRING_DIGITS_128);
> +        for (carry=sticky_bit; (!carry) && (i < min_digits); i++) {
> +         if (buffer[i] > '0') {
> +           carry = 1;
> +           break;
> +         }
> +       }
>        }
> -    }
> -               break;
> -
> -        default: break; // default added to avoid compiler warning
> +      break;
> +
> +    default: break; // default added to avoid compiler warning
>         }
>      // now form the coefficient as coeff_high*10^17+coeff_low+carry
>      scale_high = 100000000000000000ull;
> --
> 2.34.1
>


-- 
BR,
Hongtao

Reply via email to