(root)/
gcc-13.2.0/
libgcc/
config/
libbid/
bid64_to_uint64.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  #include "bid_internal.h"
      25  
      26  /*****************************************************************************
      27   *  BID64_to_uint64_rnint
      28   ****************************************************************************/
      29  
      30  #if DECIMAL_CALL_BY_REFERENCE
      31  void
      32  bid64_to_uint64_rnint (UINT64 * pres, UINT64 * px
      33  		       _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
      34  		       _EXC_INFO_PARAM) {
      35    UINT64 x = *px;
      36  #else
      37  UINT64
      38  bid64_to_uint64_rnint (UINT64 x
      39  		       _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
      40  		       _EXC_INFO_PARAM) {
      41  #endif
      42    UINT64 res;
      43    UINT64 x_sign;
      44    UINT64 x_exp;
      45    int exp;			// unbiased exponent
      46    // Note: C1 represents x_significand (UINT64)
      47    BID_UI64DOUBLE tmp1;
      48    unsigned int x_nr_bits;
      49    int q, ind, shift;
      50    UINT64 C1;
      51    UINT128 C;
      52    UINT64 Cstar;			// C* represents up to 16 decimal digits ~ 54 bits
      53    UINT128 fstar;
      54    UINT128 P128;
      55  
      56    // check for NaN or Infinity
      57    if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
      58      // set invalid flag
      59      *pfpsf |= INVALID_EXCEPTION;
      60      // return Integer Indefinite
      61      res = 0x8000000000000000ull;
      62      BID_RETURN (res);
      63    }
      64    // unpack x
      65    x_sign = x & MASK_SIGN;	// 0 for positive, MASK_SIGN for negative
      66    // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
      67    if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
      68      x_exp = (x & MASK_BINARY_EXPONENT2) >> 51;	// biased
      69      C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
      70      if (C1 > 9999999999999999ull) {	// non-canonical
      71        x_exp = 0;
      72        C1 = 0;
      73      }
      74    } else {
      75      x_exp = (x & MASK_BINARY_EXPONENT1) >> 53;	// biased
      76      C1 = x & MASK_BINARY_SIG1;
      77    }
      78  
      79    // check for zeros (possibly from non-canonical values)
      80    if (C1 == 0x0ull) {
      81      // x is 0
      82      res = 0x0000000000000000ull;
      83      BID_RETURN (res);
      84    }
      85    // x is not special and is not zero
      86  
      87    // q = nr. of decimal digits in x (1 <= q <= 54)
      88    //  determine first the nr. of bits in x
      89    if (C1 >= 0x0020000000000000ull) {	// x >= 2^53
      90      // split the 64-bit value in two 32-bit halves to avoid rounding errors
      91      if (C1 >= 0x0000000100000000ull) {	// x >= 2^32
      92        tmp1.d = (double) (C1 >> 32);	// exact conversion
      93        x_nr_bits =
      94  	33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
      95      } else {	// x < 2^32
      96        tmp1.d = (double) C1;	// exact conversion
      97        x_nr_bits =
      98  	1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
      99      }
     100    } else {	// if x < 2^53
     101      tmp1.d = (double) C1;	// exact conversion
     102      x_nr_bits =
     103        1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     104    }
     105    q = nr_digits[x_nr_bits - 1].digits;
     106    if (q == 0) {
     107      q = nr_digits[x_nr_bits - 1].digits1;
     108      if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
     109        q++;
     110    }
     111    exp = x_exp - 398;	// unbiased exponent
     112  
     113    if ((q + exp) > 20) {	// x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
     114      // set invalid flag
     115      *pfpsf |= INVALID_EXCEPTION;
     116      // return Integer Indefinite
     117      res = 0x8000000000000000ull;
     118      BID_RETURN (res);
     119    } else if ((q + exp) == 20) {	// x = c(0)c(1)...c(19).c(20)...c(q-1)
     120      // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
     121      // so x rounded to an integer may or may not fit in an unsigned 64-bit int
     122      // the cases that do not fit are identified here; the ones that fit
     123      // fall through and will be handled with other cases further,
     124      // under '1 <= q + exp <= 20'
     125      if (x_sign) {	// if n < 0 and q + exp = 20 then x is much less than -1/2
     126        // => set invalid flag
     127        *pfpsf |= INVALID_EXCEPTION;
     128        // return Integer Indefinite
     129        res = 0x8000000000000000ull;
     130        BID_RETURN (res);
     131      } else {	// if n > 0 and q + exp = 20
     132        // if n >= 2^64 - 1/2 then n is too large
     133        // <=> c(0)c(1)...c(19).c(20)...c(q-1) >= 2^64-1/2
     134        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 >= 2^64-1/2
     135        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 >= 5*(2^65-1)
     136        // <=> C * 10^(21-q) >= 0x9fffffffffffffffb, 1<=q<=16
     137        if (q == 1) {
     138  	// C * 10^20 >= 0x9fffffffffffffffb
     139  	__mul_128x64_to_128 (C, C1, ten2k128[0]);	// 10^20 * C
     140  	if (C.w[1] > 0x09 ||
     141  	    (C.w[1] == 0x09 && C.w[0] >= 0xfffffffffffffffbull)) {
     142  	  // set invalid flag
     143  	  *pfpsf |= INVALID_EXCEPTION;
     144  	  // return Integer Indefinite
     145  	  res = 0x8000000000000000ull;
     146  	  BID_RETURN (res);
     147  	}
     148  	// else cases that can be rounded to a 64-bit int fall through
     149  	// to '1 <= q + exp <= 20'
     150        } else {	// if (2 <= q <= 16) => 5 <= 21 - q <= 19
     151  	// Note: C * 10^(21-q) has 20 or 21 digits; 0x9fffffffffffffffb 
     152  	// has 21 digits
     153  	__mul_64x64_to_128MACH (C, C1, ten2k64[21 - q]);
     154  	if (C.w[1] > 0x09 ||
     155  	    (C.w[1] == 0x09 && C.w[0] >= 0xfffffffffffffffbull)) {
     156  	  // set invalid flag
     157  	  *pfpsf |= INVALID_EXCEPTION;
     158  	  // return Integer Indefinite
     159  	  res = 0x8000000000000000ull;
     160  	  BID_RETURN (res);
     161  	}
     162  	// else cases that can be rounded to a 64-bit int fall through
     163  	// to '1 <= q + exp <= 20'
     164        }
     165      }
     166    }
     167    // n is not too large to be converted to int64 if -1/2 <= n < 2^64 - 1/2
     168    // Note: some of the cases tested for above fall through to this point
     169    if ((q + exp) < 0) {	// n = +/-0.0...c(0)c(1)...c(q-1)
     170      // return 0
     171      res = 0x0000000000000000ull;
     172      BID_RETURN (res);
     173    } else if ((q + exp) == 0) {	// n = +/-0.c(0)c(1)...c(q-1)
     174      // if 0.c(0)c(1)...c(q-1) <= 0.5 <=> c(0)c(1)...c(q-1) <= 5 * 10^(q-1)
     175      //   res = 0
     176      // else if x > 0
     177      //   res = +1
     178      // else // if x < 0
     179      //   invalid exc
     180      ind = q - 1;	// 0 <= ind <= 15
     181      if (C1 <= midpoint64[ind]) {
     182        res = 0x0000000000000000ull;	// return 0
     183      } else if (!x_sign) {	// n > 0
     184        res = 0x0000000000000001ull;	// return +1
     185      } else {	// if n < 0
     186        res = 0x8000000000000000ull;
     187        *pfpsf |= INVALID_EXCEPTION;
     188        BID_RETURN (res);
     189      }
     190    } else {	// if (1 <= q + exp <= 20, 1 <= q <= 16, -15 <= exp <= 19)
     191      // x <= -1 or 1 <= x < 2^64-1/2 so if positive x can be rounded
     192      // to nearest to a 64-bit unsigned signed integer
     193      if (x_sign) {	// x <= -1
     194        // set invalid flag
     195        *pfpsf |= INVALID_EXCEPTION;
     196        // return Integer Indefinite
     197        res = 0x8000000000000000ull;
     198        BID_RETURN (res);
     199      }
     200      // 1 <= x < 2^64-1/2 so x can be rounded
     201      // to nearest to a 64-bit unsigned integer
     202      if (exp < 0) {	// 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 20
     203        ind = -exp;	// 1 <= ind <= 15; ind is a synonym for 'x'
     204        // chop off ind digits from the lower part of C1
     205        // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 64 bits
     206        C1 = C1 + midpoint64[ind - 1];
     207        // calculate C* and f*
     208        // C* is actually floor(C*) in this case
     209        // C* and f* need shifting and masking, as shown by
     210        // shiftright128[] and maskhigh128[]
     211        // 1 <= x <= 15 
     212        // kx = 10^(-x) = ten2mk64[ind - 1]
     213        // C* = (C1 + 1/2 * 10^x) * 10^(-x)
     214        // the approximation of 10^(-x) was rounded up to 54 bits
     215        __mul_64x64_to_128MACH (P128, C1, ten2mk64[ind - 1]);
     216        Cstar = P128.w[1];
     217        fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
     218        fstar.w[0] = P128.w[0];
     219        // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
     220        // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
     221        // if (0 < f* < 10^(-x)) then the result is a midpoint
     222        //   if floor(C*) is even then C* = floor(C*) - logical right
     223        //       shift; C* has p decimal digits, correct by Prop. 1)
     224        //   else if floor(C*) is odd C* = floor(C*)-1 (logical right
     225        //       shift; C* has p decimal digits, correct by Pr. 1)
     226        // else
     227        //   C* = floor(C*) (logical right shift; C has p decimal digits,
     228        //       correct by Property 1)
     229        // n = C* * 10^(e+x)
     230  
     231        // shift right C* by Ex-64 = shiftright128[ind]
     232        shift = shiftright128[ind - 1];	// 0 <= shift <= 39
     233        Cstar = Cstar >> shift;
     234  
     235        // if the result was a midpoint it was rounded away from zero, so
     236        // it will need a correction
     237        // check for midpoints
     238        if ((fstar.w[1] == 0) && fstar.w[0] &&
     239  	  (fstar.w[0] <= ten2mk128trunc[ind - 1].w[1])) {
     240  	// ten2mk128trunc[ind -1].w[1] is identical to 
     241  	// ten2mk128[ind -1].w[1]
     242  	// the result is a midpoint; round to nearest
     243  	if (Cstar & 0x01) {	// Cstar is odd; MP in [EVEN, ODD]
     244  	  // if floor(C*) is odd C = floor(C*) - 1; the result >= 1
     245  	  Cstar--;	// Cstar is now even
     246  	}	// else MP in [ODD, EVEN]
     247        }
     248        res = Cstar;	// the result is positive
     249      } else if (exp == 0) {
     250        // 1 <= q <= 10
     251        // res = +C (exact)
     252        res = C1;	// the result is positive
     253      } else {	// if (exp > 0) => 1 <= exp <= 9, 1 <= q < 9, 2 <= q + exp <= 10
     254        // res = +C * 10^exp (exact)
     255        res = C1 * ten2k64[exp];	// the result is positive
     256      }
     257    }
     258    BID_RETURN (res);
     259  }
     260  
     261  /*****************************************************************************
     262   *  BID64_to_uint64_xrnint
     263   ****************************************************************************/
     264  
     265  #if DECIMAL_CALL_BY_REFERENCE
     266  void
     267  bid64_to_uint64_xrnint (UINT64 * pres, UINT64 * px
     268  			_EXC_FLAGS_PARAM _EXC_MASKS_PARAM
     269  			_EXC_INFO_PARAM) {
     270    UINT64 x = *px;
     271  #else
     272  UINT64
     273  bid64_to_uint64_xrnint (UINT64 x
     274  			_EXC_FLAGS_PARAM _EXC_MASKS_PARAM
     275  			_EXC_INFO_PARAM) {
     276  #endif
     277    UINT64 res;
     278    UINT64 x_sign;
     279    UINT64 x_exp;
     280    int exp;			// unbiased exponent
     281    // Note: C1 represents x_significand (UINT64)
     282    UINT64 tmp64;
     283    BID_UI64DOUBLE tmp1;
     284    unsigned int x_nr_bits;
     285    int q, ind, shift;
     286    UINT64 C1;
     287    UINT128 C;
     288    UINT64 Cstar;			// C* represents up to 16 decimal digits ~ 54 bits
     289    UINT128 fstar;
     290    UINT128 P128;
     291  
     292    // check for NaN or Infinity
     293    if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
     294      // set invalid flag
     295      *pfpsf |= INVALID_EXCEPTION;
     296      // return Integer Indefinite
     297      res = 0x8000000000000000ull;
     298      BID_RETURN (res);
     299    }
     300    // unpack x
     301    x_sign = x & MASK_SIGN;	// 0 for positive, MASK_SIGN for negative
     302    // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
     303    if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
     304      x_exp = (x & MASK_BINARY_EXPONENT2) >> 51;	// biased
     305      C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
     306      if (C1 > 9999999999999999ull) {	// non-canonical
     307        x_exp = 0;
     308        C1 = 0;
     309      }
     310    } else {
     311      x_exp = (x & MASK_BINARY_EXPONENT1) >> 53;	// biased
     312      C1 = x & MASK_BINARY_SIG1;
     313    }
     314  
     315    // check for zeros (possibly from non-canonical values)
     316    if (C1 == 0x0ull) {
     317      // x is 0
     318      res = 0x0000000000000000ull;
     319      BID_RETURN (res);
     320    }
     321    // x is not special and is not zero
     322  
     323    // q = nr. of decimal digits in x (1 <= q <= 54)
     324    //  determine first the nr. of bits in x
     325    if (C1 >= 0x0020000000000000ull) {	// x >= 2^53
     326      // split the 64-bit value in two 32-bit halves to avoid rounding errors
     327      if (C1 >= 0x0000000100000000ull) {	// x >= 2^32
     328        tmp1.d = (double) (C1 >> 32);	// exact conversion
     329        x_nr_bits =
     330  	33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     331      } else {	// x < 2^32
     332        tmp1.d = (double) C1;	// exact conversion
     333        x_nr_bits =
     334  	1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     335      }
     336    } else {	// if x < 2^53
     337      tmp1.d = (double) C1;	// exact conversion
     338      x_nr_bits =
     339        1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     340    }
     341    q = nr_digits[x_nr_bits - 1].digits;
     342    if (q == 0) {
     343      q = nr_digits[x_nr_bits - 1].digits1;
     344      if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
     345        q++;
     346    }
     347    exp = x_exp - 398;	// unbiased exponent
     348  
     349    if ((q + exp) > 20) {	// x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
     350      // set invalid flag
     351      *pfpsf |= INVALID_EXCEPTION;
     352      // return Integer Indefinite
     353      res = 0x8000000000000000ull;
     354      BID_RETURN (res);
     355    } else if ((q + exp) == 20) {	// x = c(0)c(1)...c(19).c(20)...c(q-1)
     356      // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
     357      // so x rounded to an integer may or may not fit in an unsigned 64-bit int
     358      // the cases that do not fit are identified here; the ones that fit
     359      // fall through and will be handled with other cases further,
     360      // under '1 <= q + exp <= 20'
     361      if (x_sign) {	// if n < 0 and q + exp = 20 then x is much less than -1/2
     362        // => set invalid flag
     363        *pfpsf |= INVALID_EXCEPTION;
     364        // return Integer Indefinite
     365        res = 0x8000000000000000ull;
     366        BID_RETURN (res);
     367      } else {	// if n > 0 and q + exp = 20
     368        // if n >= 2^64 - 1/2 then n is too large
     369        // <=> c(0)c(1)...c(19).c(20)...c(q-1) >= 2^64-1/2
     370        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 >= 2^64-1/2
     371        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 >= 5*(2^65-1)
     372        // <=> C * 10^(21-q) >= 0x9fffffffffffffffb, 1<=q<=16
     373        if (q == 1) {
     374  	// C * 10^20 >= 0x9fffffffffffffffb
     375  	__mul_128x64_to_128 (C, C1, ten2k128[0]);	// 10^20 * C
     376  	if (C.w[1] > 0x09 ||
     377  	    (C.w[1] == 0x09 && C.w[0] >= 0xfffffffffffffffbull)) {
     378  	  // set invalid flag
     379  	  *pfpsf |= INVALID_EXCEPTION;
     380  	  // return Integer Indefinite
     381  	  res = 0x8000000000000000ull;
     382  	  BID_RETURN (res);
     383  	}
     384  	// else cases that can be rounded to a 64-bit int fall through
     385  	// to '1 <= q + exp <= 20'
     386        } else {	// if (2 <= q <= 16) => 5 <= 21 - q <= 19
     387  	// Note: C * 10^(21-q) has 20 or 21 digits; 0x9fffffffffffffffb 
     388  	// has 21 digits
     389  	__mul_64x64_to_128MACH (C, C1, ten2k64[21 - q]);
     390  	if (C.w[1] > 0x09 ||
     391  	    (C.w[1] == 0x09 && C.w[0] >= 0xfffffffffffffffbull)) {
     392  	  // set invalid flag
     393  	  *pfpsf |= INVALID_EXCEPTION;
     394  	  // return Integer Indefinite
     395  	  res = 0x8000000000000000ull;
     396  	  BID_RETURN (res);
     397  	}
     398  	// else cases that can be rounded to a 64-bit int fall through
     399  	// to '1 <= q + exp <= 20'
     400        }
     401      }
     402    }
     403    // n is not too large to be converted to int64 if -1/2 <= n < 2^64 - 1/2
     404    // Note: some of the cases tested for above fall through to this point
     405    if ((q + exp) < 0) {	// n = +/-0.0...c(0)c(1)...c(q-1)
     406      // set inexact flag
     407      *pfpsf |= INEXACT_EXCEPTION;
     408      // return 0
     409      res = 0x0000000000000000ull;
     410      BID_RETURN (res);
     411    } else if ((q + exp) == 0) {	// n = +/-0.c(0)c(1)...c(q-1)
     412      // if 0.c(0)c(1)...c(q-1) <= 0.5 <=> c(0)c(1)...c(q-1) <= 5 * 10^(q-1)
     413      //   res = 0
     414      // else if x > 0
     415      //   res = +1
     416      // else // if x < 0
     417      //   invalid exc
     418      ind = q - 1;	// 0 <= ind <= 15
     419      if (C1 <= midpoint64[ind]) {
     420        res = 0x0000000000000000ull;	// return 0
     421      } else if (!x_sign) {	// n > 0
     422        res = 0x0000000000000001ull;	// return +1
     423      } else {	// if n < 0
     424        res = 0x8000000000000000ull;
     425        *pfpsf |= INVALID_EXCEPTION;
     426        BID_RETURN (res);
     427      }
     428      // set inexact flag
     429      *pfpsf |= INEXACT_EXCEPTION;
     430    } else {	// if (1 <= q + exp <= 20, 1 <= q <= 16, -15 <= exp <= 19)
     431      // x <= -1 or 1 <= x < 2^64-1/2 so if positive x can be rounded
     432      // to nearest to a 64-bit unsigned signed integer
     433      if (x_sign) {	// x <= -1
     434        // set invalid flag
     435        *pfpsf |= INVALID_EXCEPTION;
     436        // return Integer Indefinite
     437        res = 0x8000000000000000ull;
     438        BID_RETURN (res);
     439      }
     440      // 1 <= x < 2^64-1/2 so x can be rounded
     441      // to nearest to a 64-bit unsigned integer
     442      if (exp < 0) {	// 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 20
     443        ind = -exp;	// 1 <= ind <= 15; ind is a synonym for 'x'
     444        // chop off ind digits from the lower part of C1
     445        // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 64 bits
     446        C1 = C1 + midpoint64[ind - 1];
     447        // calculate C* and f*
     448        // C* is actually floor(C*) in this case
     449        // C* and f* need shifting and masking, as shown by
     450        // shiftright128[] and maskhigh128[]
     451        // 1 <= x <= 15 
     452        // kx = 10^(-x) = ten2mk64[ind - 1]
     453        // C* = (C1 + 1/2 * 10^x) * 10^(-x)
     454        // the approximation of 10^(-x) was rounded up to 54 bits
     455        __mul_64x64_to_128MACH (P128, C1, ten2mk64[ind - 1]);
     456        Cstar = P128.w[1];
     457        fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
     458        fstar.w[0] = P128.w[0];
     459        // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
     460        // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
     461        // if (0 < f* < 10^(-x)) then the result is a midpoint
     462        //   if floor(C*) is even then C* = floor(C*) - logical right
     463        //       shift; C* has p decimal digits, correct by Prop. 1)
     464        //   else if floor(C*) is odd C* = floor(C*)-1 (logical right
     465        //       shift; C* has p decimal digits, correct by Pr. 1)
     466        // else
     467        //   C* = floor(C*) (logical right shift; C has p decimal digits,
     468        //       correct by Property 1)
     469        // n = C* * 10^(e+x)
     470  
     471        // shift right C* by Ex-64 = shiftright128[ind]
     472        shift = shiftright128[ind - 1];	// 0 <= shift <= 39
     473        Cstar = Cstar >> shift;
     474        // determine inexactness of the rounding of C*
     475        // if (0 < f* - 1/2 < 10^(-x)) then
     476        //   the result is exact
     477        // else // if (f* - 1/2 > T*) then
     478        //   the result is inexact
     479        if (ind - 1 <= 2) {	// fstar.w[1] is 0
     480  	if (fstar.w[0] > 0x8000000000000000ull) {
     481  	  // f* > 1/2 and the result may be exact
     482  	  tmp64 = fstar.w[0] - 0x8000000000000000ull;	// f* - 1/2
     483  	  if ((tmp64 > ten2mk128trunc[ind - 1].w[1])) {
     484  	    // ten2mk128trunc[ind -1].w[1] is identical to
     485  	    // ten2mk128[ind -1].w[1]
     486  	    // set the inexact flag
     487  	    *pfpsf |= INEXACT_EXCEPTION;
     488  	  }	// else the result is exact
     489  	} else {	// the result is inexact; f2* <= 1/2
     490  	  // set the inexact flag
     491  	  *pfpsf |= INEXACT_EXCEPTION;
     492  	}
     493        } else {	// if 3 <= ind - 1 <= 14
     494  	if (fstar.w[1] > onehalf128[ind - 1] ||
     495  	    (fstar.w[1] == onehalf128[ind - 1] && fstar.w[0])) {
     496  	  // f2* > 1/2 and the result may be exact
     497  	  // Calculate f2* - 1/2
     498  	  tmp64 = fstar.w[1] - onehalf128[ind - 1];
     499  	  if (tmp64 || fstar.w[0] > ten2mk128trunc[ind - 1].w[1]) {
     500  	    // ten2mk128trunc[ind -1].w[1] is identical to
     501  	    // ten2mk128[ind -1].w[1]
     502  	    // set the inexact flag
     503  	    *pfpsf |= INEXACT_EXCEPTION;
     504  	  }	// else the result is exact
     505  	} else {	// the result is inexact; f2* <= 1/2
     506  	  // set the inexact flag
     507  	  *pfpsf |= INEXACT_EXCEPTION;
     508  	}
     509        }
     510  
     511        // if the result was a midpoint it was rounded away from zero, so
     512        // it will need a correction
     513        // check for midpoints
     514        if ((fstar.w[1] == 0) && fstar.w[0] &&
     515  	  (fstar.w[0] <= ten2mk128trunc[ind - 1].w[1])) {
     516  	// ten2mk128trunc[ind -1].w[1] is identical to 
     517  	// ten2mk128[ind -1].w[1]
     518  	// the result is a midpoint; round to nearest
     519  	if (Cstar & 0x01) {	// Cstar is odd; MP in [EVEN, ODD]
     520  	  // if floor(C*) is odd C = floor(C*) - 1; the result >= 1
     521  	  Cstar--;	// Cstar is now even
     522  	}	// else MP in [ODD, EVEN]
     523        }
     524        res = Cstar;	// the result is positive
     525      } else if (exp == 0) {
     526        // 1 <= q <= 10
     527        // res = +C (exact)
     528        res = C1;	// the result is positive
     529      } else {	// if (exp > 0) => 1 <= exp <= 9, 1 <= q < 9, 2 <= q + exp <= 10
     530        // res = +C * 10^exp (exact)
     531        res = C1 * ten2k64[exp];	// the result is positive
     532      }
     533    }
     534    BID_RETURN (res);
     535  }
     536  
     537  /*****************************************************************************
     538   *  BID64_to_uint64_floor
     539   ****************************************************************************/
     540  
     541  #if DECIMAL_CALL_BY_REFERENCE
     542  void
     543  bid64_to_uint64_floor (UINT64 * pres, UINT64 * px
     544  		       _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
     545  		       _EXC_INFO_PARAM) {
     546    UINT64 x = *px;
     547  #else
     548  UINT64
     549  bid64_to_uint64_floor (UINT64 x
     550  		       _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
     551  		       _EXC_INFO_PARAM) {
     552  #endif
     553    UINT64 res;
     554    UINT64 x_sign;
     555    UINT64 x_exp;
     556    int exp;			// unbiased exponent
     557    // Note: C1 represents x_significand (UINT64)
     558    BID_UI64DOUBLE tmp1;
     559    unsigned int x_nr_bits;
     560    int q, ind, shift;
     561    UINT64 C1;
     562    UINT128 C;
     563    UINT64 Cstar;			// C* represents up to 16 decimal digits ~ 54 bits
     564    UINT128 P128;
     565  
     566    // check for NaN or Infinity
     567    if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
     568      // set invalid flag
     569      *pfpsf |= INVALID_EXCEPTION;
     570      // return Integer Indefinite
     571      res = 0x8000000000000000ull;
     572      BID_RETURN (res);
     573    }
     574    // unpack x
     575    x_sign = x & MASK_SIGN;	// 0 for positive, MASK_SIGN for negative
     576    // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
     577    if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
     578      x_exp = (x & MASK_BINARY_EXPONENT2) >> 51;	// biased
     579      C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
     580      if (C1 > 9999999999999999ull) {	// non-canonical
     581        x_exp = 0;
     582        C1 = 0;
     583      }
     584    } else {
     585      x_exp = (x & MASK_BINARY_EXPONENT1) >> 53;	// biased
     586      C1 = x & MASK_BINARY_SIG1;
     587    }
     588  
     589    // check for zeros (possibly from non-canonical values)
     590    if (C1 == 0x0ull) {
     591      // x is 0
     592      res = 0x0000000000000000ull;
     593      BID_RETURN (res);
     594    }
     595    // x is not special and is not zero
     596  
     597    if (x_sign) {	// if n < 0 the conversion is invalid
     598      // set invalid flag
     599      *pfpsf |= INVALID_EXCEPTION;
     600      // return Integer Indefinite
     601      res = 0x8000000000000000ull;
     602      BID_RETURN (res);
     603    }
     604    // q = nr. of decimal digits in x (1 <= q <= 54)
     605    //  determine first the nr. of bits in x
     606    if (C1 >= 0x0020000000000000ull) {	// x >= 2^53
     607      // split the 64-bit value in two 32-bit halves to avoid rounding errors
     608      if (C1 >= 0x0000000100000000ull) {	// x >= 2^32
     609        tmp1.d = (double) (C1 >> 32);	// exact conversion
     610        x_nr_bits =
     611  	33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     612      } else {	// x < 2^32
     613        tmp1.d = (double) C1;	// exact conversion
     614        x_nr_bits =
     615  	1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     616      }
     617    } else {	// if x < 2^53
     618      tmp1.d = (double) C1;	// exact conversion
     619      x_nr_bits =
     620        1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     621    }
     622    q = nr_digits[x_nr_bits - 1].digits;
     623    if (q == 0) {
     624      q = nr_digits[x_nr_bits - 1].digits1;
     625      if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
     626        q++;
     627    }
     628    exp = x_exp - 398;	// unbiased exponent
     629  
     630    if ((q + exp) > 20) {	// x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
     631      // set invalid flag
     632      *pfpsf |= INVALID_EXCEPTION;
     633      // return Integer Indefinite
     634      res = 0x8000000000000000ull;
     635      BID_RETURN (res);
     636    } else if ((q + exp) == 20) {	// x = c(0)c(1)...c(19).c(20)...c(q-1)
     637      // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
     638      // so x rounded to an integer may or may not fit in an unsigned 64-bit int
     639      // the cases that do not fit are identified here; the ones that fit
     640      // fall through and will be handled with other cases further,
     641      // under '1 <= q + exp <= 20'
     642      // n > 0 and q + exp = 20
     643      // if n >= 2^64 then n is too large
     644      // <=> c(0)c(1)...c(19).c(20)...c(q-1) >= 2^64
     645      // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 >= 2^64
     646      // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 >= 5*(2^65)
     647      // <=> C * 10^(21-q) >= 0xa0000000000000000, 1<=q<=16
     648      if (q == 1) {
     649        // C * 10^20 >= 0xa0000000000000000
     650        __mul_128x64_to_128 (C, C1, ten2k128[0]);	// 10^20 * C
     651        if (C.w[1] >= 0x0a) {
     652  	// actually C.w[1] == 0x0a && C.w[0] >= 0x0000000000000000ull) {
     653  	// set invalid flag
     654  	*pfpsf |= INVALID_EXCEPTION;
     655  	// return Integer Indefinite
     656  	res = 0x8000000000000000ull;
     657  	BID_RETURN (res);
     658        }
     659        // else cases that can be rounded to a 64-bit int fall through
     660        // to '1 <= q + exp <= 20'
     661      } else {	// if (2 <= q <= 16) => 5 <= 21 - q <= 19
     662        // Note: C * 10^(21-q) has 20 or 21 digits; 0xa0000000000000000 
     663        // has 21 digits
     664        __mul_64x64_to_128MACH (C, C1, ten2k64[21 - q]);
     665        if (C.w[1] >= 0x0a) {
     666  	// actually C.w[1] == 0x0a && C.w[0] >= 0x0000000000000000ull) {
     667  	// set invalid flag
     668  	*pfpsf |= INVALID_EXCEPTION;
     669  	// return Integer Indefinite
     670  	res = 0x8000000000000000ull;
     671  	BID_RETURN (res);
     672        }
     673        // else cases that can be rounded to a 64-bit int fall through
     674        // to '1 <= q + exp <= 20'
     675      }
     676    }
     677    // n is not too large to be converted to int64 if -1 < n < 2^64
     678    // Note: some of the cases tested for above fall through to this point
     679    if ((q + exp) <= 0) {	// n = +0.[0...0]c(0)c(1)...c(q-1)
     680      // return 0
     681      res = 0x0000000000000000ull;
     682      BID_RETURN (res);
     683    } else {	// if (1 <= q + exp <= 20, 1 <= q <= 16, -15 <= exp <= 19)
     684      // 1 <= x < 2^64 so x can be rounded
     685      // to nearest to a 64-bit unsigned signed integer
     686      if (exp < 0) {	// 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 20
     687        ind = -exp;	// 1 <= ind <= 15; ind is a synonym for 'x'
     688        // chop off ind digits from the lower part of C1
     689        // C1 fits in 64 bits
     690        // calculate C* and f*
     691        // C* is actually floor(C*) in this case
     692        // C* and f* need shifting and masking, as shown by
     693        // shiftright128[] and maskhigh128[]
     694        // 1 <= x <= 15 
     695        // kx = 10^(-x) = ten2mk64[ind - 1]
     696        // C* = C1 * 10^(-x)
     697        // the approximation of 10^(-x) was rounded up to 54 bits
     698        __mul_64x64_to_128MACH (P128, C1, ten2mk64[ind - 1]);
     699        Cstar = P128.w[1];
     700        // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
     701        // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
     702        // C* = floor(C*) (logical right shift; C has p decimal digits,
     703        //     correct by Property 1)
     704        // n = C* * 10^(e+x)
     705  
     706        // shift right C* by Ex-64 = shiftright128[ind]
     707        shift = shiftright128[ind - 1];	// 0 <= shift <= 39
     708        Cstar = Cstar >> shift;
     709        res = Cstar;	// the result is positive
     710      } else if (exp == 0) {
     711        // 1 <= q <= 10
     712        // res = +C (exact)
     713        res = C1;	// the result is positive
     714      } else {	// if (exp > 0) => 1 <= exp <= 9, 1 <= q < 9, 2 <= q + exp <= 10
     715        // res = +C * 10^exp (exact)
     716        res = C1 * ten2k64[exp];	// the result is positive
     717      }
     718    }
     719    BID_RETURN (res);
     720  }
     721  
     722  /*****************************************************************************
     723   *  BID64_to_uint64_xfloor
     724   ****************************************************************************/
     725  
     726  #if DECIMAL_CALL_BY_REFERENCE
     727  void
     728  bid64_to_uint64_xfloor (UINT64 * pres, UINT64 * px
     729  			_EXC_FLAGS_PARAM _EXC_MASKS_PARAM
     730  			_EXC_INFO_PARAM) {
     731    UINT64 x = *px;
     732  #else
     733  UINT64
     734  bid64_to_uint64_xfloor (UINT64 x
     735  			_EXC_FLAGS_PARAM _EXC_MASKS_PARAM
     736  			_EXC_INFO_PARAM) {
     737  #endif
     738    UINT64 res;
     739    UINT64 x_sign;
     740    UINT64 x_exp;
     741    int exp;			// unbiased exponent
     742    // Note: C1 represents x_significand (UINT64)
     743    BID_UI64DOUBLE tmp1;
     744    unsigned int x_nr_bits;
     745    int q, ind, shift;
     746    UINT64 C1;
     747    UINT128 C;
     748    UINT64 Cstar;			// C* represents up to 16 decimal digits ~ 54 bits
     749    UINT128 fstar;
     750    UINT128 P128;
     751  
     752    // check for NaN or Infinity
     753    if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
     754      // set invalid flag
     755      *pfpsf |= INVALID_EXCEPTION;
     756      // return Integer Indefinite
     757      res = 0x8000000000000000ull;
     758      BID_RETURN (res);
     759    }
     760    // unpack x
     761    x_sign = x & MASK_SIGN;	// 0 for positive, MASK_SIGN for negative
     762    // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
     763    if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
     764      x_exp = (x & MASK_BINARY_EXPONENT2) >> 51;	// biased
     765      C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
     766      if (C1 > 9999999999999999ull) {	// non-canonical
     767        x_exp = 0;
     768        C1 = 0;
     769      }
     770    } else {
     771      x_exp = (x & MASK_BINARY_EXPONENT1) >> 53;	// biased
     772      C1 = x & MASK_BINARY_SIG1;
     773    }
     774  
     775    // check for zeros (possibly from non-canonical values)
     776    if (C1 == 0x0ull) {
     777      // x is 0
     778      res = 0x0000000000000000ull;
     779      BID_RETURN (res);
     780    }
     781    // x is not special and is not zero
     782  
     783    if (x_sign) {	// if n < 0 the conversion is invalid
     784      // set invalid flag
     785      *pfpsf |= INVALID_EXCEPTION;
     786      // return Integer Indefinite
     787      res = 0x8000000000000000ull;
     788      BID_RETURN (res);
     789    }
     790    // q = nr. of decimal digits in x (1 <= q <= 54)
     791    //  determine first the nr. of bits in x
     792    if (C1 >= 0x0020000000000000ull) {	// x >= 2^53
     793      // split the 64-bit value in two 32-bit halves to avoid rounding errors
     794      if (C1 >= 0x0000000100000000ull) {	// x >= 2^32
     795        tmp1.d = (double) (C1 >> 32);	// exact conversion
     796        x_nr_bits =
     797  	33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     798      } else {	// x < 2^32
     799        tmp1.d = (double) C1;	// exact conversion
     800        x_nr_bits =
     801  	1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     802      }
     803    } else {	// if x < 2^53
     804      tmp1.d = (double) C1;	// exact conversion
     805      x_nr_bits =
     806        1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     807    }
     808    q = nr_digits[x_nr_bits - 1].digits;
     809    if (q == 0) {
     810      q = nr_digits[x_nr_bits - 1].digits1;
     811      if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
     812        q++;
     813    }
     814    exp = x_exp - 398;	// unbiased exponent
     815  
     816    if ((q + exp) > 20) {	// x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
     817      // set invalid flag
     818      *pfpsf |= INVALID_EXCEPTION;
     819      // return Integer Indefinite
     820      res = 0x8000000000000000ull;
     821      BID_RETURN (res);
     822    } else if ((q + exp) == 20) {	// x = c(0)c(1)...c(19).c(20)...c(q-1)
     823      // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
     824      // so x rounded to an integer may or may not fit in an unsigned 64-bit int
     825      // the cases that do not fit are identified here; the ones that fit
     826      // fall through and will be handled with other cases further,
     827      // under '1 <= q + exp <= 20'
     828      // n > 0 and q + exp = 20
     829      // if n >= 2^64 then n is too large
     830      // <=> c(0)c(1)...c(19).c(20)...c(q-1) >= 2^64
     831      // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 >= 2^64
     832      // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 >= 5*(2^65)
     833      // <=> C * 10^(21-q) >= 0xa0000000000000000, 1<=q<=16
     834      if (q == 1) {
     835        // C * 10^20 >= 0xa0000000000000000
     836        __mul_128x64_to_128 (C, C1, ten2k128[0]);	// 10^20 * C
     837        if (C.w[1] >= 0x0a) {
     838  	// actually C.w[1] == 0x0a && C.w[0] >= 0x0000000000000000ull) {
     839  	// set invalid flag
     840  	*pfpsf |= INVALID_EXCEPTION;
     841  	// return Integer Indefinite
     842  	res = 0x8000000000000000ull;
     843  	BID_RETURN (res);
     844        }
     845        // else cases that can be rounded to a 64-bit int fall through
     846        // to '1 <= q + exp <= 20'
     847      } else {	// if (2 <= q <= 16) => 5 <= 21 - q <= 19
     848        // Note: C * 10^(21-q) has 20 or 21 digits; 0xa0000000000000000 
     849        // has 21 digits
     850        __mul_64x64_to_128MACH (C, C1, ten2k64[21 - q]);
     851        if (C.w[1] >= 0x0a) {
     852  	// actually C.w[1] == 0x0a && C.w[0] >= 0x0000000000000000ull) {
     853  	// set invalid flag
     854  	*pfpsf |= INVALID_EXCEPTION;
     855  	// return Integer Indefinite
     856  	res = 0x8000000000000000ull;
     857  	BID_RETURN (res);
     858        }
     859        // else cases that can be rounded to a 64-bit int fall through
     860        // to '1 <= q + exp <= 20'
     861      }
     862    }
     863    // n is not too large to be converted to int64 if -1 < n < 2^64
     864    // Note: some of the cases tested for above fall through to this point
     865    if ((q + exp) <= 0) {	// n = +0.[0...0]c(0)c(1)...c(q-1)
     866      // set inexact flag
     867      *pfpsf |= INEXACT_EXCEPTION;
     868      // return 0
     869      res = 0x0000000000000000ull;
     870      BID_RETURN (res);
     871    } else {	// if (1 <= q + exp <= 20, 1 <= q <= 16, -15 <= exp <= 19)
     872      // 1 <= x < 2^64 so x can be rounded
     873      // to nearest to a 64-bit unsigned signed integer
     874      if (exp < 0) {	// 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 20
     875        ind = -exp;	// 1 <= ind <= 15; ind is a synonym for 'x'
     876        // chop off ind digits from the lower part of C1
     877        // C1 fits in 64 bits
     878        // calculate C* and f*
     879        // C* is actually floor(C*) in this case
     880        // C* and f* need shifting and masking, as shown by
     881        // shiftright128[] and maskhigh128[]
     882        // 1 <= x <= 15 
     883        // kx = 10^(-x) = ten2mk64[ind - 1]
     884        // C* = C1 * 10^(-x)
     885        // the approximation of 10^(-x) was rounded up to 54 bits
     886        __mul_64x64_to_128MACH (P128, C1, ten2mk64[ind - 1]);
     887        Cstar = P128.w[1];
     888        fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
     889        fstar.w[0] = P128.w[0];
     890        // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
     891        // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
     892        // C* = floor(C*) (logical right shift; C has p decimal digits,
     893        //     correct by Property 1)
     894        // n = C* * 10^(e+x)
     895  
     896        // shift right C* by Ex-64 = shiftright128[ind]
     897        shift = shiftright128[ind - 1];	// 0 <= shift <= 39
     898        Cstar = Cstar >> shift;
     899        // determine inexactness of the rounding of C*
     900        // if (0 < f* < 10^(-x)) then
     901        //   the result is exact
     902        // else // if (f* > T*) then
     903        //   the result is inexact
     904        if (ind - 1 <= 2) {	// fstar.w[1] is 0
     905  	if (fstar.w[0] > ten2mk128trunc[ind - 1].w[1]) {
     906  	  // ten2mk128trunc[ind -1].w[1] is identical to
     907  	  // ten2mk128[ind -1].w[1]
     908  	  // set the inexact flag
     909  	  *pfpsf |= INEXACT_EXCEPTION;
     910  	}	// else the result is exact
     911        } else {	// if 3 <= ind - 1 <= 14
     912  	if (fstar.w[1] || fstar.w[0] > ten2mk128trunc[ind - 1].w[1]) {
     913  	  // ten2mk128trunc[ind -1].w[1] is identical to
     914  	  // ten2mk128[ind -1].w[1]
     915  	  // set the inexact flag
     916  	  *pfpsf |= INEXACT_EXCEPTION;
     917  	}	// else the result is exact
     918        }
     919  
     920        res = Cstar;	// the result is positive
     921      } else if (exp == 0) {
     922        // 1 <= q <= 10
     923        // res = +C (exact)
     924        res = C1;	// the result is positive
     925      } else {	// if (exp > 0) => 1 <= exp <= 9, 1 <= q < 9, 2 <= q + exp <= 10
     926        // res = +C * 10^exp (exact)
     927        res = C1 * ten2k64[exp];	// the result is positive
     928      }
     929    }
     930    BID_RETURN (res);
     931  }
     932  
     933  /*****************************************************************************
     934   *  BID64_to_uint64_ceil
     935   ****************************************************************************/
     936  
     937  #if DECIMAL_CALL_BY_REFERENCE
     938  void
     939  bid64_to_uint64_ceil (UINT64 * pres, UINT64 * px
     940  		      _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
     941  		      _EXC_INFO_PARAM) {
     942    UINT64 x = *px;
     943  #else
     944  UINT64
     945  bid64_to_uint64_ceil (UINT64 x
     946  		      _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
     947  		      _EXC_INFO_PARAM) {
     948  #endif
     949    UINT64 res;
     950    UINT64 x_sign;
     951    UINT64 x_exp;
     952    int exp;			// unbiased exponent
     953    // Note: C1 represents x_significand (UINT64)
     954    BID_UI64DOUBLE tmp1;
     955    unsigned int x_nr_bits;
     956    int q, ind, shift;
     957    UINT64 C1;
     958    UINT128 C;
     959    UINT64 Cstar;			// C* represents up to 16 decimal digits ~ 54 bits
     960    UINT128 fstar;
     961    UINT128 P128;
     962  
     963    // check for NaN or Infinity
     964    if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
     965      // set invalid flag
     966      *pfpsf |= INVALID_EXCEPTION;
     967      // return Integer Indefinite
     968      res = 0x8000000000000000ull;
     969      BID_RETURN (res);
     970    }
     971    // unpack x
     972    x_sign = x & MASK_SIGN;	// 0 for positive, MASK_SIGN for negative
     973    // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
     974    if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
     975      x_exp = (x & MASK_BINARY_EXPONENT2) >> 51;	// biased
     976      C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
     977      if (C1 > 9999999999999999ull) {	// non-canonical
     978        x_exp = 0;
     979        C1 = 0;
     980      }
     981    } else {
     982      x_exp = (x & MASK_BINARY_EXPONENT1) >> 53;	// biased
     983      C1 = x & MASK_BINARY_SIG1;
     984    }
     985  
     986    // check for zeros (possibly from non-canonical values)
     987    if (C1 == 0x0ull) {
     988      // x is 0
     989      res = 0x0000000000000000ull;
     990      BID_RETURN (res);
     991    }
     992    // x is not special and is not zero
     993  
     994    // q = nr. of decimal digits in x (1 <= q <= 54)
     995    //  determine first the nr. of bits in x
     996    if (C1 >= 0x0020000000000000ull) {	// x >= 2^53
     997      // split the 64-bit value in two 32-bit halves to avoid rounding errors
     998      if (C1 >= 0x0000000100000000ull) {	// x >= 2^32
     999        tmp1.d = (double) (C1 >> 32);	// exact conversion
    1000        x_nr_bits =
    1001  	33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1002      } else {	// x < 2^32
    1003        tmp1.d = (double) C1;	// exact conversion
    1004        x_nr_bits =
    1005  	1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1006      }
    1007    } else {	// if x < 2^53
    1008      tmp1.d = (double) C1;	// exact conversion
    1009      x_nr_bits =
    1010        1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1011    }
    1012    q = nr_digits[x_nr_bits - 1].digits;
    1013    if (q == 0) {
    1014      q = nr_digits[x_nr_bits - 1].digits1;
    1015      if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
    1016        q++;
    1017    }
    1018    exp = x_exp - 398;	// unbiased exponent
    1019  
    1020    if ((q + exp) > 20) {	// x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
    1021      // set invalid flag
    1022      *pfpsf |= INVALID_EXCEPTION;
    1023      // return Integer Indefinite
    1024      res = 0x8000000000000000ull;
    1025      BID_RETURN (res);
    1026    } else if ((q + exp) == 20) {	// x = c(0)c(1)...c(19).c(20)...c(q-1)
    1027      // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
    1028      // so x rounded to an integer may or may not fit in an unsigned 64-bit int
    1029      // the cases that do not fit are identified here; the ones that fit
    1030      // fall through and will be handled with other cases further,
    1031      // under '1 <= q + exp <= 20'
    1032      if (x_sign) {	// if n < 0 and q + exp = 20 then x is much less than -1
    1033        // => set invalid flag
    1034        *pfpsf |= INVALID_EXCEPTION;
    1035        // return Integer Indefinite
    1036        res = 0x8000000000000000ull;
    1037        BID_RETURN (res);
    1038      } else {	// if n > 0 and q + exp = 20
    1039        // if n > 2^64 - 1 then n is too large
    1040        // <=> c(0)c(1)...c(19).c(20)...c(q-1) > 2^64 - 1
    1041        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 > 2^64 - 1
    1042        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 >= 5*(2^65 - 2)
    1043        // <=> C * 10^(21-q) > 0x9fffffffffffffff6, 1<=q<=16
    1044        if (q == 1) {
    1045  	// C * 10^20 > 0x9fffffffffffffff6
    1046  	__mul_128x64_to_128 (C, C1, ten2k128[0]);	// 10^20 * C
    1047  	if (C.w[1] > 0x09 ||
    1048  	    (C.w[1] == 0x09 && C.w[0] > 0xfffffffffffffff6ull)) {
    1049  	  // set invalid flag
    1050  	  *pfpsf |= INVALID_EXCEPTION;
    1051  	  // return Integer Indefinite
    1052  	  res = 0x8000000000000000ull;
    1053  	  BID_RETURN (res);
    1054  	}
    1055  	// else cases that can be rounded to a 64-bit int fall through
    1056  	// to '1 <= q + exp <= 20'
    1057        } else {	// if (2 <= q <= 16) => 5 <= 21 - q <= 19
    1058  	// Note: C * 10^(21-q) has 20 or 21 digits; 0x9fffffffffffffff6
    1059  	// has 21 digits
    1060  	__mul_64x64_to_128MACH (C, C1, ten2k64[21 - q]);
    1061  	if (C.w[1] > 0x09 ||
    1062  	    (C.w[1] == 0x09 && C.w[0] > 0xfffffffffffffff6ull)) {
    1063  	  // set invalid flag
    1064  	  *pfpsf |= INVALID_EXCEPTION;
    1065  	  // return Integer Indefinite
    1066  	  res = 0x8000000000000000ull;
    1067  	  BID_RETURN (res);
    1068  	}
    1069  	// else cases that can be rounded to a 64-bit int fall through
    1070  	// to '1 <= q + exp <= 20'
    1071        }
    1072      }
    1073    }
    1074    // n is not too large to be converted to int64 if -1 < n < 2^64
    1075    // Note: some of the cases tested for above fall through to this point
    1076    if ((q + exp) <= 0) {	// n = +/-0.[0...0]c(0)c(1)...c(q-1)
    1077      // return 0 or 1
    1078      if (x_sign)
    1079        res = 0x0000000000000000ull;
    1080      else
    1081        res = 0x0000000000000001ull;
    1082      BID_RETURN (res);
    1083    } else {	// if (1 <= q + exp <= 20, 1 <= q <= 16, -15 <= exp <= 19)
    1084      // x <= -1 or 1 <= x <= 2^64 - 1 so if positive x can be rounded
    1085      // to nearest to a 64-bit unsigned signed integer
    1086      if (x_sign) {	// x <= -1
    1087        // set invalid flag
    1088        *pfpsf |= INVALID_EXCEPTION;
    1089        // return Integer Indefinite
    1090        res = 0x8000000000000000ull;
    1091        BID_RETURN (res);
    1092      }
    1093      // 1 <= x <= 2^64 - 1 so x can be rounded
    1094      // to nearest to a 64-bit unsigned integer
    1095      if (exp < 0) {	// 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 20
    1096        ind = -exp;	// 1 <= ind <= 15; ind is a synonym for 'x'
    1097        // chop off ind digits from the lower part of C1
    1098        // C1 fits in 64 bits
    1099        // calculate C* and f*
    1100        // C* is actually floor(C*) in this case
    1101        // C* and f* need shifting and masking, as shown by
    1102        // shiftright128[] and maskhigh128[]
    1103        // 1 <= x <= 15 
    1104        // kx = 10^(-x) = ten2mk64[ind - 1]
    1105        // C* = C1 * 10^(-x)
    1106        // the approximation of 10^(-x) was rounded up to 54 bits
    1107        __mul_64x64_to_128MACH (P128, C1, ten2mk64[ind - 1]);
    1108        Cstar = P128.w[1];
    1109        fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
    1110        fstar.w[0] = P128.w[0];
    1111        // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
    1112        // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
    1113        // C* = floor(C*) (logical right shift; C has p decimal digits,
    1114        //     correct by Property 1)
    1115        // n = C* * 10^(e+x)
    1116  
    1117        // shift right C* by Ex-64 = shiftright128[ind]
    1118        shift = shiftright128[ind - 1];	// 0 <= shift <= 39
    1119        Cstar = Cstar >> shift;
    1120        // determine inexactness of the rounding of C*
    1121        // if (0 < f* < 10^(-x)) then
    1122        //   the result is exact
    1123        // else // if (f* > T*) then
    1124        //   the result is inexact
    1125        if (ind - 1 <= 2) {	// fstar.w[1] is 0
    1126  	if (fstar.w[0] > ten2mk128trunc[ind - 1].w[1]) {
    1127  	  // ten2mk128trunc[ind -1].w[1] is identical to
    1128  	  // ten2mk128[ind -1].w[1]
    1129  	  Cstar++;
    1130  	}	// else the result is exact
    1131        } else {	// if 3 <= ind - 1 <= 14
    1132  	if (fstar.w[1] || fstar.w[0] > ten2mk128trunc[ind - 1].w[1]) {
    1133  	  // ten2mk128trunc[ind -1].w[1] is identical to
    1134  	  // ten2mk128[ind -1].w[1]
    1135  	  Cstar++;
    1136  	}	// else the result is exact
    1137        }
    1138  
    1139        res = Cstar;	// the result is positive
    1140      } else if (exp == 0) {
    1141        // 1 <= q <= 10
    1142        // res = +C (exact)
    1143        res = C1;	// the result is positive
    1144      } else {	// if (exp > 0) => 1 <= exp <= 9, 1 <= q < 9, 2 <= q + exp <= 10
    1145        // res = +C * 10^exp (exact)
    1146        res = C1 * ten2k64[exp];	// the result is positive
    1147      }
    1148    }
    1149    BID_RETURN (res);
    1150  }
    1151  
    1152  /*****************************************************************************
    1153   *  BID64_to_uint64_xceil
    1154   ****************************************************************************/
    1155  
    1156  #if DECIMAL_CALL_BY_REFERENCE
    1157  void
    1158  bid64_to_uint64_xceil (UINT64 * pres, UINT64 * px
    1159  		       _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
    1160  		       _EXC_INFO_PARAM) {
    1161    UINT64 x = *px;
    1162  #else
    1163  UINT64
    1164  bid64_to_uint64_xceil (UINT64 x
    1165  		       _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
    1166  		       _EXC_INFO_PARAM) {
    1167  #endif
    1168    UINT64 res;
    1169    UINT64 x_sign;
    1170    UINT64 x_exp;
    1171    int exp;			// unbiased exponent
    1172    // Note: C1 represents x_significand (UINT64)
    1173    BID_UI64DOUBLE tmp1;
    1174    unsigned int x_nr_bits;
    1175    int q, ind, shift;
    1176    UINT64 C1;
    1177    UINT128 C;
    1178    UINT64 Cstar;			// C* represents up to 16 decimal digits ~ 54 bits
    1179    UINT128 fstar;
    1180    UINT128 P128;
    1181  
    1182    // check for NaN or Infinity
    1183    if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
    1184      // set invalid flag
    1185      *pfpsf |= INVALID_EXCEPTION;
    1186      // return Integer Indefinite
    1187      res = 0x8000000000000000ull;
    1188      BID_RETURN (res);
    1189    }
    1190    // unpack x
    1191    x_sign = x & MASK_SIGN;	// 0 for positive, MASK_SIGN for negative
    1192    // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
    1193    if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
    1194      x_exp = (x & MASK_BINARY_EXPONENT2) >> 51;	// biased
    1195      C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
    1196      if (C1 > 9999999999999999ull) {	// non-canonical
    1197        x_exp = 0;
    1198        C1 = 0;
    1199      }
    1200    } else {
    1201      x_exp = (x & MASK_BINARY_EXPONENT1) >> 53;	// biased
    1202      C1 = x & MASK_BINARY_SIG1;
    1203    }
    1204  
    1205    // check for zeros (possibly from non-canonical values)
    1206    if (C1 == 0x0ull) {
    1207      // x is 0
    1208      res = 0x0000000000000000ull;
    1209      BID_RETURN (res);
    1210    }
    1211    // x is not special and is not zero
    1212  
    1213    // q = nr. of decimal digits in x (1 <= q <= 54)
    1214    //  determine first the nr. of bits in x
    1215    if (C1 >= 0x0020000000000000ull) {	// x >= 2^53
    1216      // split the 64-bit value in two 32-bit halves to avoid rounding errors
    1217      if (C1 >= 0x0000000100000000ull) {	// x >= 2^32
    1218        tmp1.d = (double) (C1 >> 32);	// exact conversion
    1219        x_nr_bits =
    1220  	33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1221      } else {	// x < 2^32
    1222        tmp1.d = (double) C1;	// exact conversion
    1223        x_nr_bits =
    1224  	1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1225      }
    1226    } else {	// if x < 2^53
    1227      tmp1.d = (double) C1;	// exact conversion
    1228      x_nr_bits =
    1229        1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1230    }
    1231    q = nr_digits[x_nr_bits - 1].digits;
    1232    if (q == 0) {
    1233      q = nr_digits[x_nr_bits - 1].digits1;
    1234      if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
    1235        q++;
    1236    }
    1237    exp = x_exp - 398;	// unbiased exponent
    1238  
    1239    if ((q + exp) > 20) {	// x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
    1240      // set invalid flag
    1241      *pfpsf |= INVALID_EXCEPTION;
    1242      // return Integer Indefinite
    1243      res = 0x8000000000000000ull;
    1244      BID_RETURN (res);
    1245    } else if ((q + exp) == 20) {	// x = c(0)c(1)...c(19).c(20)...c(q-1)
    1246      // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
    1247      // so x rounded to an integer may or may not fit in an unsigned 64-bit int
    1248      // the cases that do not fit are identified here; the ones that fit
    1249      // fall through and will be handled with other cases further,
    1250      // under '1 <= q + exp <= 20'
    1251      if (x_sign) {	// if n < 0 and q + exp = 20 then x is much less than -1
    1252        // => set invalid flag
    1253        *pfpsf |= INVALID_EXCEPTION;
    1254        // return Integer Indefinite
    1255        res = 0x8000000000000000ull;
    1256        BID_RETURN (res);
    1257      } else {	// if n > 0 and q + exp = 20
    1258        // if n > 2^64 - 1 then n is too large
    1259        // <=> c(0)c(1)...c(19).c(20)...c(q-1) > 2^64 - 1
    1260        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 > 2^64 - 1
    1261        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 >= 5*(2^65 - 2)
    1262        // <=> C * 10^(21-q) > 0x9fffffffffffffff6, 1<=q<=16
    1263        if (q == 1) {
    1264  	// C * 10^20 > 0x9fffffffffffffff6
    1265  	__mul_128x64_to_128 (C, C1, ten2k128[0]);	// 10^20 * C
    1266  	if (C.w[1] > 0x09 ||
    1267  	    (C.w[1] == 0x09 && C.w[0] > 0xfffffffffffffff6ull)) {
    1268  	  // set invalid flag
    1269  	  *pfpsf |= INVALID_EXCEPTION;
    1270  	  // return Integer Indefinite
    1271  	  res = 0x8000000000000000ull;
    1272  	  BID_RETURN (res);
    1273  	}
    1274  	// else cases that can be rounded to a 64-bit int fall through
    1275  	// to '1 <= q + exp <= 20'
    1276        } else {	// if (2 <= q <= 16) => 5 <= 21 - q <= 19
    1277  	// Note: C * 10^(21-q) has 20 or 21 digits; 0x9fffffffffffffff6
    1278  	// has 21 digits
    1279  	__mul_64x64_to_128MACH (C, C1, ten2k64[21 - q]);
    1280  	if (C.w[1] > 0x09 ||
    1281  	    (C.w[1] == 0x09 && C.w[0] > 0xfffffffffffffff6ull)) {
    1282  	  // set invalid flag
    1283  	  *pfpsf |= INVALID_EXCEPTION;
    1284  	  // return Integer Indefinite
    1285  	  res = 0x8000000000000000ull;
    1286  	  BID_RETURN (res);
    1287  	}
    1288  	// else cases that can be rounded to a 64-bit int fall through
    1289  	// to '1 <= q + exp <= 20'
    1290        }
    1291      }
    1292    }
    1293    // n is not too large to be converted to int64 if -1 < n < 2^64
    1294    // Note: some of the cases tested for above fall through to this point
    1295    if ((q + exp) <= 0) {	// n = +/-0.[0...0]c(0)c(1)...c(q-1)
    1296      // set inexact flag
    1297      *pfpsf |= INEXACT_EXCEPTION;
    1298      // return 0 or 1
    1299      if (x_sign)
    1300        res = 0x0000000000000000ull;
    1301      else
    1302        res = 0x0000000000000001ull;
    1303      BID_RETURN (res);
    1304    } else {	// if (1 <= q + exp <= 20, 1 <= q <= 16, -15 <= exp <= 19)
    1305      // x <= -1 or 1 <= x <= 2^64 - 1 so if positive x can be rounded
    1306      // to nearest to a 64-bit unsigned signed integer
    1307      if (x_sign) {	// x <= -1
    1308        // set invalid flag
    1309        *pfpsf |= INVALID_EXCEPTION;
    1310        // return Integer Indefinite
    1311        res = 0x8000000000000000ull;
    1312        BID_RETURN (res);
    1313      }
    1314      // 1 <= x <= 2^64 - 1 so x can be rounded
    1315      // to nearest to a 64-bit unsigned integer
    1316      if (exp < 0) {	// 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 20
    1317        ind = -exp;	// 1 <= ind <= 15; ind is a synonym for 'x'
    1318        // chop off ind digits from the lower part of C1
    1319        // C1 fits in 64 bits
    1320        // calculate C* and f*
    1321        // C* is actually floor(C*) in this case
    1322        // C* and f* need shifting and masking, as shown by
    1323        // shiftright128[] and maskhigh128[]
    1324        // 1 <= x <= 15 
    1325        // kx = 10^(-x) = ten2mk64[ind - 1]
    1326        // C* = C1 * 10^(-x)
    1327        // the approximation of 10^(-x) was rounded up to 54 bits
    1328        __mul_64x64_to_128MACH (P128, C1, ten2mk64[ind - 1]);
    1329        Cstar = P128.w[1];
    1330        fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
    1331        fstar.w[0] = P128.w[0];
    1332        // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
    1333        // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
    1334        // C* = floor(C*) (logical right shift; C has p decimal digits,
    1335        //     correct by Property 1)
    1336        // n = C* * 10^(e+x)
    1337  
    1338        // shift right C* by Ex-64 = shiftright128[ind]
    1339        shift = shiftright128[ind - 1];	// 0 <= shift <= 39
    1340        Cstar = Cstar >> shift;
    1341        // determine inexactness of the rounding of C*
    1342        // if (0 < f* < 10^(-x)) then
    1343        //   the result is exact
    1344        // else // if (f* > T*) then
    1345        //   the result is inexact
    1346        if (ind - 1 <= 2) {	// fstar.w[1] is 0
    1347  	if (fstar.w[0] > ten2mk128trunc[ind - 1].w[1]) {
    1348  	  // ten2mk128trunc[ind -1].w[1] is identical to
    1349  	  // ten2mk128[ind -1].w[1]
    1350  	  Cstar++;
    1351  	  // set the inexact flag
    1352  	  *pfpsf |= INEXACT_EXCEPTION;
    1353  	}	// else the result is exact
    1354        } else {	// if 3 <= ind - 1 <= 14
    1355  	if (fstar.w[1] || fstar.w[0] > ten2mk128trunc[ind - 1].w[1]) {
    1356  	  // ten2mk128trunc[ind -1].w[1] is identical to
    1357  	  // ten2mk128[ind -1].w[1]
    1358  	  Cstar++;
    1359  	  // set the inexact flag
    1360  	  *pfpsf |= INEXACT_EXCEPTION;
    1361  	}	// else the result is exact
    1362        }
    1363  
    1364        res = Cstar;	// the result is positive
    1365      } else if (exp == 0) {
    1366        // 1 <= q <= 10
    1367        // res = +C (exact)
    1368        res = C1;	// the result is positive
    1369      } else {	// if (exp > 0) => 1 <= exp <= 9, 1 <= q < 9, 2 <= q + exp <= 10
    1370        // res = +C * 10^exp (exact)
    1371        res = C1 * ten2k64[exp];	// the result is positive
    1372      }
    1373    }
    1374    BID_RETURN (res);
    1375  }
    1376  
    1377  /*****************************************************************************
    1378   *  BID64_to_uint64_int
    1379   ****************************************************************************/
    1380  
    1381  #if DECIMAL_CALL_BY_REFERENCE
    1382  void
    1383  bid64_to_uint64_int (UINT64 * pres, UINT64 * px
    1384  		     _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) 
    1385  {
    1386    UINT64 x = *px;
    1387  #else
    1388  UINT64
    1389  bid64_to_uint64_int (UINT64 x
    1390  		     _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) 
    1391  {
    1392  #endif
    1393    UINT64 res;
    1394    UINT64 x_sign;
    1395    UINT64 x_exp;
    1396    int exp;			// unbiased exponent
    1397    // Note: C1 represents x_significand (UINT64)
    1398    BID_UI64DOUBLE tmp1;
    1399    unsigned int x_nr_bits;
    1400    int q, ind, shift;
    1401    UINT64 C1;
    1402    UINT128 C;
    1403    UINT64 Cstar;			// C* represents up to 16 decimal digits ~ 54 bits
    1404    UINT128 P128;
    1405  
    1406    // check for NaN or Infinity
    1407    if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
    1408      // set invalid flag
    1409      *pfpsf |= INVALID_EXCEPTION;
    1410      // return Integer Indefinite
    1411      res = 0x8000000000000000ull;
    1412      BID_RETURN (res);
    1413    }
    1414    // unpack x
    1415    x_sign = x & MASK_SIGN;	// 0 for positive, MASK_SIGN for negative
    1416    // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
    1417    if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
    1418      x_exp = (x & MASK_BINARY_EXPONENT2) >> 51;	// biased
    1419      C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
    1420      if (C1 > 9999999999999999ull) {	// non-canonical
    1421        x_exp = 0;
    1422        C1 = 0;
    1423      }
    1424    } else {
    1425      x_exp = (x & MASK_BINARY_EXPONENT1) >> 53;	// biased
    1426      C1 = x & MASK_BINARY_SIG1;
    1427    }
    1428  
    1429    // check for zeros (possibly from non-canonical values)
    1430    if (C1 == 0x0ull) {
    1431      // x is 0
    1432      res = 0x0000000000000000ull;
    1433      BID_RETURN (res);
    1434    }
    1435    // x is not special and is not zero
    1436  
    1437    // q = nr. of decimal digits in x (1 <= q <= 54)
    1438    //  determine first the nr. of bits in x
    1439    if (C1 >= 0x0020000000000000ull) {	// x >= 2^53
    1440      // split the 64-bit value in two 32-bit halves to avoid rounding errors
    1441      if (C1 >= 0x0000000100000000ull) {	// x >= 2^32
    1442        tmp1.d = (double) (C1 >> 32);	// exact conversion
    1443        x_nr_bits =
    1444  	33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1445      } else {	// x < 2^32
    1446        tmp1.d = (double) C1;	// exact conversion
    1447        x_nr_bits =
    1448  	1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1449      }
    1450    } else {	// if x < 2^53
    1451      tmp1.d = (double) C1;	// exact conversion
    1452      x_nr_bits =
    1453        1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1454    }
    1455    q = nr_digits[x_nr_bits - 1].digits;
    1456    if (q == 0) {
    1457      q = nr_digits[x_nr_bits - 1].digits1;
    1458      if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
    1459        q++;
    1460    }
    1461    exp = x_exp - 398;	// unbiased exponent
    1462  
    1463    if ((q + exp) > 20) {	// x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
    1464      // set invalid flag
    1465      *pfpsf |= INVALID_EXCEPTION;
    1466      // return Integer Indefinite
    1467      res = 0x8000000000000000ull;
    1468      BID_RETURN (res);
    1469    } else if ((q + exp) == 20) {	// x = c(0)c(1)...c(19).c(20)...c(q-1)
    1470      // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
    1471      // so x rounded to an integer may or may not fit in an unsigned 64-bit int
    1472      // the cases that do not fit are identified here; the ones that fit
    1473      // fall through and will be handled with other cases further,
    1474      // under '1 <= q + exp <= 20'
    1475      if (x_sign) {	// if n < 0 and q + exp = 20 then x is much less than -1
    1476        // => set invalid flag
    1477        *pfpsf |= INVALID_EXCEPTION;
    1478        // return Integer Indefinite
    1479        res = 0x8000000000000000ull;
    1480        BID_RETURN (res);
    1481      } else {	// if n > 0 and q + exp = 20
    1482        // if n >= 2^64 then n is too large
    1483        // <=> c(0)c(1)...c(19).c(20)...c(q-1) >= 2^64
    1484        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 >= 2^64
    1485        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 >= 5*(2^65)
    1486        // <=> C * 10^(21-q) >= 0xa0000000000000000, 1<=q<=16
    1487        if (q == 1) {
    1488  	// C * 10^20 >= 0xa0000000000000000
    1489  	__mul_128x64_to_128 (C, C1, ten2k128[0]);	// 10^20 * C
    1490  	if (C.w[1] >= 0x0a) {
    1491  	  // actually C.w[1] == 0x0a && C.w[0] >= 0x0000000000000000ull) {
    1492  	  // set invalid flag
    1493  	  *pfpsf |= INVALID_EXCEPTION;
    1494  	  // return Integer Indefinite
    1495  	  res = 0x8000000000000000ull;
    1496  	  BID_RETURN (res);
    1497  	}
    1498  	// else cases that can be rounded to a 64-bit int fall through
    1499  	// to '1 <= q + exp <= 20'
    1500        } else {	// if (2 <= q <= 16) => 5 <= 21 - q <= 19
    1501  	// Note: C * 10^(21-q) has 20 or 21 digits; 0xa0000000000000000 
    1502  	// has 21 digits
    1503  	__mul_64x64_to_128MACH (C, C1, ten2k64[21 - q]);
    1504  	if (C.w[1] >= 0x0a) {
    1505  	  // actually C.w[1] == 0x0a && C.w[0] >= 0x0000000000000000ull) {
    1506  	  // set invalid flag
    1507  	  *pfpsf |= INVALID_EXCEPTION;
    1508  	  // return Integer Indefinite
    1509  	  res = 0x8000000000000000ull;
    1510  	  BID_RETURN (res);
    1511  	}
    1512  	// else cases that can be rounded to a 64-bit int fall through
    1513  	// to '1 <= q + exp <= 20'
    1514        }
    1515      }
    1516    }
    1517    // n is not too large to be converted to int64 if -1 < n < 2^64
    1518    // Note: some of the cases tested for above fall through to this point
    1519    if ((q + exp) <= 0) {	// n = +/-0.[0...0]c(0)c(1)...c(q-1)
    1520      // return 0
    1521      res = 0x0000000000000000ull;
    1522      BID_RETURN (res);
    1523    } else {	// if (1 <= q + exp <= 20, 1 <= q <= 16, -15 <= exp <= 19)
    1524      // x <= -1 or 1 <= x < 2^64 so if positive x can be rounded
    1525      // to nearest to a 64-bit unsigned signed integer
    1526      if (x_sign) {	// x <= -1
    1527        // set invalid flag
    1528        *pfpsf |= INVALID_EXCEPTION;
    1529        // return Integer Indefinite
    1530        res = 0x8000000000000000ull;
    1531        BID_RETURN (res);
    1532      }
    1533      // 1 <= x < 2^64 so x can be rounded
    1534      // to nearest to a 64-bit unsigned integer
    1535      if (exp < 0) {	// 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 20
    1536        ind = -exp;	// 1 <= ind <= 15; ind is a synonym for 'x'
    1537        // chop off ind digits from the lower part of C1
    1538        // C1 fits in 64 bits
    1539        // calculate C* and f*
    1540        // C* is actually floor(C*) in this case
    1541        // C* and f* need shifting and masking, as shown by
    1542        // shiftright128[] and maskhigh128[]
    1543        // 1 <= x <= 15 
    1544        // kx = 10^(-x) = ten2mk64[ind - 1]
    1545        // C* = C1 * 10^(-x)
    1546        // the approximation of 10^(-x) was rounded up to 54 bits
    1547        __mul_64x64_to_128MACH (P128, C1, ten2mk64[ind - 1]);
    1548        Cstar = P128.w[1];
    1549        // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
    1550        // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
    1551        // C* = floor(C*) (logical right shift; C has p decimal digits,
    1552        //     correct by Property 1)
    1553        // n = C* * 10^(e+x)
    1554  
    1555        // shift right C* by Ex-64 = shiftright128[ind]
    1556        shift = shiftright128[ind - 1];	// 0 <= shift <= 39
    1557        Cstar = Cstar >> shift;
    1558        res = Cstar;	// the result is positive
    1559      } else if (exp == 0) {
    1560        // 1 <= q <= 10
    1561        // res = +C (exact)
    1562        res = C1;	// the result is positive
    1563      } else {	// if (exp > 0) => 1 <= exp <= 9, 1 <= q < 9, 2 <= q + exp <= 10
    1564        // res = +C * 10^exp (exact)
    1565        res = C1 * ten2k64[exp];	// the result is positive
    1566      }
    1567    }
    1568    BID_RETURN (res);
    1569  }
    1570  
    1571  /*****************************************************************************
    1572   *  BID64_to_uint64_xint
    1573   ****************************************************************************/
    1574  
    1575  #if DECIMAL_CALL_BY_REFERENCE
    1576  void
    1577  bid64_to_uint64_xint (UINT64 * pres, UINT64 * px
    1578  		      _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
    1579  		      _EXC_INFO_PARAM) {
    1580    UINT64 x = *px;
    1581  #else
    1582  UINT64
    1583  bid64_to_uint64_xint (UINT64 x
    1584  		      _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
    1585  		      _EXC_INFO_PARAM) {
    1586  #endif
    1587    UINT64 res;
    1588    UINT64 x_sign;
    1589    UINT64 x_exp;
    1590    int exp;			// unbiased exponent
    1591    // Note: C1 represents x_significand (UINT64)
    1592    BID_UI64DOUBLE tmp1;
    1593    unsigned int x_nr_bits;
    1594    int q, ind, shift;
    1595    UINT64 C1;
    1596    UINT128 C;
    1597    UINT64 Cstar;			// C* represents up to 16 decimal digits ~ 54 bits
    1598    UINT128 fstar;
    1599    UINT128 P128;
    1600  
    1601    // check for NaN or Infinity
    1602    if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
    1603      // set invalid flag
    1604      *pfpsf |= INVALID_EXCEPTION;
    1605      // return Integer Indefinite
    1606      res = 0x8000000000000000ull;
    1607      BID_RETURN (res);
    1608    }
    1609    // unpack x
    1610    x_sign = x & MASK_SIGN;	// 0 for positive, MASK_SIGN for negative
    1611    // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
    1612    if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
    1613      x_exp = (x & MASK_BINARY_EXPONENT2) >> 51;	// biased
    1614      C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
    1615      if (C1 > 9999999999999999ull) {	// non-canonical
    1616        x_exp = 0;
    1617        C1 = 0;
    1618      }
    1619    } else {
    1620      x_exp = (x & MASK_BINARY_EXPONENT1) >> 53;	// biased
    1621      C1 = x & MASK_BINARY_SIG1;
    1622    }
    1623  
    1624    // check for zeros (possibly from non-canonical values)
    1625    if (C1 == 0x0ull) {
    1626      // x is 0
    1627      res = 0x0000000000000000ull;
    1628      BID_RETURN (res);
    1629    }
    1630    // x is not special and is not zero
    1631  
    1632    // q = nr. of decimal digits in x (1 <= q <= 54)
    1633    //  determine first the nr. of bits in x
    1634    if (C1 >= 0x0020000000000000ull) {	// x >= 2^53
    1635      // split the 64-bit value in two 32-bit halves to avoid rounding errors
    1636      if (C1 >= 0x0000000100000000ull) {	// x >= 2^32
    1637        tmp1.d = (double) (C1 >> 32);	// exact conversion
    1638        x_nr_bits =
    1639  	33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1640      } else {	// x < 2^32
    1641        tmp1.d = (double) C1;	// exact conversion
    1642        x_nr_bits =
    1643  	1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1644      }
    1645    } else {	// if x < 2^53
    1646      tmp1.d = (double) C1;	// exact conversion
    1647      x_nr_bits =
    1648        1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1649    }
    1650    q = nr_digits[x_nr_bits - 1].digits;
    1651    if (q == 0) {
    1652      q = nr_digits[x_nr_bits - 1].digits1;
    1653      if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
    1654        q++;
    1655    }
    1656    exp = x_exp - 398;	// unbiased exponent
    1657  
    1658    if ((q + exp) > 20) {	// x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
    1659      // set invalid flag
    1660      *pfpsf |= INVALID_EXCEPTION;
    1661      // return Integer Indefinite
    1662      res = 0x8000000000000000ull;
    1663      BID_RETURN (res);
    1664    } else if ((q + exp) == 20) {	// x = c(0)c(1)...c(19).c(20)...c(q-1)
    1665      // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
    1666      // so x rounded to an integer may or may not fit in an unsigned 64-bit int
    1667      // the cases that do not fit are identified here; the ones that fit
    1668      // fall through and will be handled with other cases further,
    1669      // under '1 <= q + exp <= 20'
    1670      if (x_sign) {	// if n < 0 and q + exp = 20 then x is much less than -1
    1671        // => set invalid flag
    1672        *pfpsf |= INVALID_EXCEPTION;
    1673        // return Integer Indefinite
    1674        res = 0x8000000000000000ull;
    1675        BID_RETURN (res);
    1676      } else {	// if n > 0 and q + exp = 20
    1677        // if n >= 2^64 then n is too large
    1678        // <=> c(0)c(1)...c(19).c(20)...c(q-1) >= 2^64
    1679        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 >= 2^64
    1680        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 >= 5*(2^65)
    1681        // <=> C * 10^(21-q) >= 0xa0000000000000000, 1<=q<=16
    1682        if (q == 1) {
    1683  	// C * 10^20 >= 0xa0000000000000000
    1684  	__mul_128x64_to_128 (C, C1, ten2k128[0]);	// 10^20 * C
    1685  	if (C.w[1] >= 0x0a) {
    1686  	  // actually C.w[1] == 0x0a && C.w[0] >= 0x0000000000000000ull) {
    1687  	  // set invalid flag
    1688  	  *pfpsf |= INVALID_EXCEPTION;
    1689  	  // return Integer Indefinite
    1690  	  res = 0x8000000000000000ull;
    1691  	  BID_RETURN (res);
    1692  	}
    1693  	// else cases that can be rounded to a 64-bit int fall through
    1694  	// to '1 <= q + exp <= 20'
    1695        } else {	// if (2 <= q <= 16) => 5 <= 21 - q <= 19
    1696  	// Note: C * 10^(21-q) has 20 or 21 digits; 0xa0000000000000000 
    1697  	// has 21 digits
    1698  	__mul_64x64_to_128MACH (C, C1, ten2k64[21 - q]);
    1699  	if (C.w[1] >= 0x0a) {
    1700  	  // actually C.w[1] == 0x0a && C.w[0] >= 0x0000000000000000ull) {
    1701  	  // set invalid flag
    1702  	  *pfpsf |= INVALID_EXCEPTION;
    1703  	  // return Integer Indefinite
    1704  	  res = 0x8000000000000000ull;
    1705  	  BID_RETURN (res);
    1706  	}
    1707  	// else cases that can be rounded to a 64-bit int fall through
    1708  	// to '1 <= q + exp <= 20'
    1709        }
    1710      }
    1711    }
    1712    // n is not too large to be converted to int64 if -1 < n < 2^64
    1713    // Note: some of the cases tested for above fall through to this point
    1714    if ((q + exp) <= 0) {	// n = +/-0.[0...0]c(0)c(1)...c(q-1)
    1715      // set inexact flag
    1716      *pfpsf |= INEXACT_EXCEPTION;
    1717      // return 0
    1718      res = 0x0000000000000000ull;
    1719      BID_RETURN (res);
    1720    } else {	// if (1 <= q + exp <= 20, 1 <= q <= 16, -15 <= exp <= 19)
    1721      // x <= -1 or 1 <= x < 2^64 so if positive x can be rounded
    1722      // to nearest to a 64-bit unsigned signed integer
    1723      if (x_sign) {	// x <= -1
    1724        // set invalid flag
    1725        *pfpsf |= INVALID_EXCEPTION;
    1726        // return Integer Indefinite
    1727        res = 0x8000000000000000ull;
    1728        BID_RETURN (res);
    1729      }
    1730      // 1 <= x < 2^64 so x can be rounded
    1731      // to nearest to a 64-bit unsigned integer
    1732      if (exp < 0) {	// 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 20
    1733        ind = -exp;	// 1 <= ind <= 15; ind is a synonym for 'x'
    1734        // chop off ind digits from the lower part of C1
    1735        // C1 fits in 64 bits
    1736        // calculate C* and f*
    1737        // C* is actually floor(C*) in this case
    1738        // C* and f* need shifting and masking, as shown by
    1739        // shiftright128[] and maskhigh128[]
    1740        // 1 <= x <= 15 
    1741        // kx = 10^(-x) = ten2mk64[ind - 1]
    1742        // C* = C1 * 10^(-x)
    1743        // the approximation of 10^(-x) was rounded up to 54 bits
    1744        __mul_64x64_to_128MACH (P128, C1, ten2mk64[ind - 1]);
    1745        Cstar = P128.w[1];
    1746        fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
    1747        fstar.w[0] = P128.w[0];
    1748        // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
    1749        // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
    1750        // C* = floor(C*) (logical right shift; C has p decimal digits,
    1751        //     correct by Property 1)
    1752        // n = C* * 10^(e+x)
    1753  
    1754        // shift right C* by Ex-64 = shiftright128[ind]
    1755        shift = shiftright128[ind - 1];	// 0 <= shift <= 39
    1756        Cstar = Cstar >> shift;
    1757        // determine inexactness of the rounding of C*
    1758        // if (0 < f* < 10^(-x)) then
    1759        //   the result is exact
    1760        // else // if (f* > T*) then
    1761        //   the result is inexact
    1762        if (ind - 1 <= 2) {	// fstar.w[1] is 0
    1763  	if (fstar.w[0] > ten2mk128trunc[ind - 1].w[1]) {
    1764  	  // ten2mk128trunc[ind -1].w[1] is identical to
    1765  	  // ten2mk128[ind -1].w[1]
    1766  	  // set the inexact flag
    1767  	  *pfpsf |= INEXACT_EXCEPTION;
    1768  	}	// else the result is exact
    1769        } else {	// if 3 <= ind - 1 <= 14
    1770  	if (fstar.w[1] || fstar.w[0] > ten2mk128trunc[ind - 1].w[1]) {
    1771  	  // ten2mk128trunc[ind -1].w[1] is identical to
    1772  	  // ten2mk128[ind -1].w[1]
    1773  	  // set the inexact flag
    1774  	  *pfpsf |= INEXACT_EXCEPTION;
    1775  	}	// else the result is exact
    1776        }
    1777  
    1778        res = Cstar;	// the result is positive
    1779      } else if (exp == 0) {
    1780        // 1 <= q <= 10
    1781        // res = +C (exact)
    1782        res = C1;	// the result is positive
    1783      } else {	// if (exp > 0) => 1 <= exp <= 9, 1 <= q < 9, 2 <= q + exp <= 10
    1784        // res = +C * 10^exp (exact)
    1785        res = C1 * ten2k64[exp];	// the result is positive
    1786      }
    1787    }
    1788    BID_RETURN (res);
    1789  }
    1790  
    1791  /*****************************************************************************
    1792   *  BID64_to_uint64_rninta
    1793   ****************************************************************************/
    1794  
    1795  #if DECIMAL_CALL_BY_REFERENCE
    1796  void
    1797  bid64_to_uint64_rninta (UINT64 * pres, UINT64 * px
    1798  			_EXC_FLAGS_PARAM _EXC_MASKS_PARAM
    1799  			_EXC_INFO_PARAM) {
    1800    UINT64 x = *px;
    1801  #else
    1802  UINT64
    1803  bid64_to_uint64_rninta (UINT64 x
    1804  			_EXC_FLAGS_PARAM _EXC_MASKS_PARAM
    1805  			_EXC_INFO_PARAM) {
    1806  #endif
    1807    UINT64 res;
    1808    UINT64 x_sign;
    1809    UINT64 x_exp;
    1810    int exp;			// unbiased exponent
    1811    // Note: C1 represents x_significand (UINT64)
    1812    BID_UI64DOUBLE tmp1;
    1813    unsigned int x_nr_bits;
    1814    int q, ind, shift;
    1815    UINT64 C1;
    1816    UINT128 C;
    1817    UINT64 Cstar;			// C* represents up to 16 decimal digits ~ 54 bits
    1818    UINT128 P128;
    1819  
    1820    // check for NaN or Infinity
    1821    if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
    1822      // set invalid flag
    1823      *pfpsf |= INVALID_EXCEPTION;
    1824      // return Integer Indefinite
    1825      res = 0x8000000000000000ull;
    1826      BID_RETURN (res);
    1827    }
    1828    // unpack x
    1829    x_sign = x & MASK_SIGN;	// 0 for positive, MASK_SIGN for negative
    1830    // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
    1831    if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
    1832      x_exp = (x & MASK_BINARY_EXPONENT2) >> 51;	// biased
    1833      C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
    1834      if (C1 > 9999999999999999ull) {	// non-canonical
    1835        x_exp = 0;
    1836        C1 = 0;
    1837      }
    1838    } else {
    1839      x_exp = (x & MASK_BINARY_EXPONENT1) >> 53;	// biased
    1840      C1 = x & MASK_BINARY_SIG1;
    1841    }
    1842  
    1843    // check for zeros (possibly from non-canonical values)
    1844    if (C1 == 0x0ull) {
    1845      // x is 0
    1846      res = 0x0000000000000000ull;
    1847      BID_RETURN (res);
    1848    }
    1849    // x is not special and is not zero
    1850  
    1851    // q = nr. of decimal digits in x (1 <= q <= 54)
    1852    //  determine first the nr. of bits in x
    1853    if (C1 >= 0x0020000000000000ull) {	// x >= 2^53
    1854      // split the 64-bit value in two 32-bit halves to avoid rounding errors
    1855      if (C1 >= 0x0000000100000000ull) {	// x >= 2^32
    1856        tmp1.d = (double) (C1 >> 32);	// exact conversion
    1857        x_nr_bits =
    1858  	33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1859      } else {	// x < 2^32
    1860        tmp1.d = (double) C1;	// exact conversion
    1861        x_nr_bits =
    1862  	1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1863      }
    1864    } else {	// if x < 2^53
    1865      tmp1.d = (double) C1;	// exact conversion
    1866      x_nr_bits =
    1867        1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1868    }
    1869    q = nr_digits[x_nr_bits - 1].digits;
    1870    if (q == 0) {
    1871      q = nr_digits[x_nr_bits - 1].digits1;
    1872      if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
    1873        q++;
    1874    }
    1875    exp = x_exp - 398;	// unbiased exponent
    1876  
    1877    if ((q + exp) > 20) {	// x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
    1878      // set invalid flag
    1879      *pfpsf |= INVALID_EXCEPTION;
    1880      // return Integer Indefinite
    1881      res = 0x8000000000000000ull;
    1882      BID_RETURN (res);
    1883    } else if ((q + exp) == 20) {	// x = c(0)c(1)...c(19).c(20)...c(q-1)
    1884      // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
    1885      // so x rounded to an integer may or may not fit in an unsigned 64-bit int
    1886      // the cases that do not fit are identified here; the ones that fit
    1887      // fall through and will be handled with other cases further,
    1888      // under '1 <= q + exp <= 20'
    1889      if (x_sign) {	// if n < 0 and q + exp = 20 then x is much less than -1/2
    1890        // => set invalid flag
    1891        *pfpsf |= INVALID_EXCEPTION;
    1892        // return Integer Indefinite
    1893        res = 0x8000000000000000ull;
    1894        BID_RETURN (res);
    1895      } else {	// if n > 0 and q + exp = 20
    1896        // if n >= 2^64 - 1/2 then n is too large
    1897        // <=> c(0)c(1)...c(19).c(20)...c(q-1) >= 2^64-1/2
    1898        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 >= 2^64-1/2
    1899        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 >= 5*(2^65-1)
    1900        // <=> C * 10^(21-q) >= 0x9fffffffffffffffb, 1<=q<=16
    1901        if (q == 1) {
    1902  	// C * 10^20 >= 0x9fffffffffffffffb
    1903  	__mul_128x64_to_128 (C, C1, ten2k128[0]);	// 10^20 * C
    1904  	if (C.w[1] > 0x09 ||
    1905  	    (C.w[1] == 0x09 && C.w[0] >= 0xfffffffffffffffbull)) {
    1906  	  // set invalid flag
    1907  	  *pfpsf |= INVALID_EXCEPTION;
    1908  	  // return Integer Indefinite
    1909  	  res = 0x8000000000000000ull;
    1910  	  BID_RETURN (res);
    1911  	}
    1912  	// else cases that can be rounded to a 64-bit int fall through
    1913  	// to '1 <= q + exp <= 20'
    1914        } else {	// if (2 <= q <= 16) => 5 <= 21 - q <= 19
    1915  	// Note: C * 10^(21-q) has 20 or 21 digits; 0x9fffffffffffffffb 
    1916  	// has 21 digits
    1917  	__mul_64x64_to_128MACH (C, C1, ten2k64[21 - q]);
    1918  	if (C.w[1] > 0x09 ||
    1919  	    (C.w[1] == 0x09 && C.w[0] >= 0xfffffffffffffffbull)) {
    1920  	  // set invalid flag
    1921  	  *pfpsf |= INVALID_EXCEPTION;
    1922  	  // return Integer Indefinite
    1923  	  res = 0x8000000000000000ull;
    1924  	  BID_RETURN (res);
    1925  	}
    1926  	// else cases that can be rounded to a 64-bit int fall through
    1927  	// to '1 <= q + exp <= 20'
    1928        }
    1929      }
    1930    }
    1931    // n is not too large to be converted to int64 if -1/2 <= n < 2^64 - 1/2
    1932    // Note: some of the cases tested for above fall through to this point
    1933    if ((q + exp) < 0) {	// n = +/-0.0...c(0)c(1)...c(q-1)
    1934      // return 0
    1935      res = 0x0000000000000000ull;
    1936      BID_RETURN (res);
    1937    } else if ((q + exp) == 0) {	// n = +/-0.c(0)c(1)...c(q-1)
    1938      // if 0.c(0)c(1)...c(q-1) < 0.5 <=> c(0)c(1)...c(q-1) < 5 * 10^(q-1)
    1939      //   res = 0
    1940      // else if x > 0
    1941      //   res = +1
    1942      // else // if x < 0
    1943      //   invalid exc
    1944      ind = q - 1;	// 0 <= ind <= 15
    1945      if (C1 < midpoint64[ind]) {
    1946        res = 0x0000000000000000ull;	// return 0
    1947      } else if (!x_sign) {	// n > 0
    1948        res = 0x0000000000000001ull;	// return +1
    1949      } else {	// if n < 0
    1950        res = 0x8000000000000000ull;
    1951        *pfpsf |= INVALID_EXCEPTION;
    1952        BID_RETURN (res);
    1953      }
    1954    } else {	// if (1 <= q + exp <= 20, 1 <= q <= 16, -15 <= exp <= 19)
    1955      // x <= -1 or 1 <= x < 2^64-1/2 so if positive x can be rounded
    1956      // to nearest to a 64-bit unsigned signed integer
    1957      if (x_sign) {	// x <= -1
    1958        // set invalid flag
    1959        *pfpsf |= INVALID_EXCEPTION;
    1960        // return Integer Indefinite
    1961        res = 0x8000000000000000ull;
    1962        BID_RETURN (res);
    1963      }
    1964      // 1 <= x < 2^64-1/2 so x can be rounded
    1965      // to nearest to a 64-bit unsigned integer
    1966      if (exp < 0) {	// 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 20
    1967        ind = -exp;	// 1 <= ind <= 15; ind is a synonym for 'x'
    1968        // chop off ind digits from the lower part of C1
    1969        // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 64 bits
    1970        C1 = C1 + midpoint64[ind - 1];
    1971        // calculate C* and f*
    1972        // C* is actually floor(C*) in this case
    1973        // C* and f* need shifting and masking, as shown by
    1974        // shiftright128[] and maskhigh128[]
    1975        // 1 <= x <= 15 
    1976        // kx = 10^(-x) = ten2mk64[ind - 1]
    1977        // C* = (C1 + 1/2 * 10^x) * 10^(-x)
    1978        // the approximation of 10^(-x) was rounded up to 54 bits
    1979        __mul_64x64_to_128MACH (P128, C1, ten2mk64[ind - 1]);
    1980        Cstar = P128.w[1];
    1981        // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
    1982        // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
    1983        // if (0 < f* < 10^(-x)) then the result is a midpoint
    1984        //   if floor(C*) is even then C* = floor(C*) - logical right
    1985        //       shift; C* has p decimal digits, correct by Prop. 1)
    1986        //   else if floor(C*) is odd C* = floor(C*)-1 (logical right
    1987        //       shift; C* has p decimal digits, correct by Pr. 1)
    1988        // else
    1989        //   C* = floor(C*) (logical right shift; C has p decimal digits,
    1990        //       correct by Property 1)
    1991        // n = C* * 10^(e+x)
    1992  
    1993        // shift right C* by Ex-64 = shiftright128[ind]
    1994        shift = shiftright128[ind - 1];	// 0 <= shift <= 39
    1995        Cstar = Cstar >> shift;
    1996  
    1997        // if the result was a midpoint it was rounded away from zero
    1998        res = Cstar;	// the result is positive
    1999      } else if (exp == 0) {
    2000        // 1 <= q <= 10
    2001        // res = +C (exact)
    2002        res = C1;	// the result is positive
    2003      } else {	// if (exp > 0) => 1 <= exp <= 9, 1 <= q < 9, 2 <= q + exp <= 10
    2004        // res = +C * 10^exp (exact)
    2005        res = C1 * ten2k64[exp];	// the result is positive
    2006      }
    2007    }
    2008    BID_RETURN (res);
    2009  }
    2010  
    2011  /*****************************************************************************
    2012   *  BID64_to_uint64_xrninta
    2013   ****************************************************************************/
    2014  
    2015  #if DECIMAL_CALL_BY_REFERENCE
    2016  void
    2017  bid64_to_uint64_xrninta (UINT64 * pres, UINT64 * px
    2018  			 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
    2019  			 _EXC_INFO_PARAM) {
    2020    UINT64 x = *px;
    2021  #else
    2022  UINT64
    2023  bid64_to_uint64_xrninta (UINT64 x
    2024  			 _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
    2025  			 _EXC_INFO_PARAM) {
    2026  #endif
    2027    UINT64 res;
    2028    UINT64 x_sign;
    2029    UINT64 x_exp;
    2030    int exp;			// unbiased exponent
    2031    // Note: C1 represents x_significand (UINT64)
    2032    UINT64 tmp64;
    2033    BID_UI64DOUBLE tmp1;
    2034    unsigned int x_nr_bits;
    2035    int q, ind, shift;
    2036    UINT64 C1;
    2037    UINT128 C;
    2038    UINT64 Cstar;			// C* represents up to 16 decimal digits ~ 54 bits
    2039    UINT128 fstar;
    2040    UINT128 P128;
    2041  
    2042    // check for NaN or Infinity
    2043    if ((x & MASK_NAN) == MASK_NAN || (x & MASK_INF) == MASK_INF) {
    2044      // set invalid flag
    2045      *pfpsf |= INVALID_EXCEPTION;
    2046      // return Integer Indefinite
    2047      res = 0x8000000000000000ull;
    2048      BID_RETURN (res);
    2049    }
    2050    // unpack x
    2051    x_sign = x & MASK_SIGN;	// 0 for positive, MASK_SIGN for negative
    2052    // if steering bits are 11 (condition will be 0), then exponent is G[0:w+1] =>
    2053    if ((x & MASK_STEERING_BITS) == MASK_STEERING_BITS) {
    2054      x_exp = (x & MASK_BINARY_EXPONENT2) >> 51;	// biased
    2055      C1 = (x & MASK_BINARY_SIG2) | MASK_BINARY_OR2;
    2056      if (C1 > 9999999999999999ull) {	// non-canonical
    2057        x_exp = 0;
    2058        C1 = 0;
    2059      }
    2060    } else {
    2061      x_exp = (x & MASK_BINARY_EXPONENT1) >> 53;	// biased
    2062      C1 = x & MASK_BINARY_SIG1;
    2063    }
    2064  
    2065    // check for zeros (possibly from non-canonical values)
    2066    if (C1 == 0x0ull) {
    2067      // x is 0
    2068      res = 0x0000000000000000ull;
    2069      BID_RETURN (res);
    2070    }
    2071    // x is not special and is not zero
    2072  
    2073    // q = nr. of decimal digits in x (1 <= q <= 54)
    2074    //  determine first the nr. of bits in x
    2075    if (C1 >= 0x0020000000000000ull) {	// x >= 2^53
    2076      // split the 64-bit value in two 32-bit halves to avoid rounding errors
    2077      if (C1 >= 0x0000000100000000ull) {	// x >= 2^32
    2078        tmp1.d = (double) (C1 >> 32);	// exact conversion
    2079        x_nr_bits =
    2080  	33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    2081      } else {	// x < 2^32
    2082        tmp1.d = (double) C1;	// exact conversion
    2083        x_nr_bits =
    2084  	1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    2085      }
    2086    } else {	// if x < 2^53
    2087      tmp1.d = (double) C1;	// exact conversion
    2088      x_nr_bits =
    2089        1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    2090    }
    2091    q = nr_digits[x_nr_bits - 1].digits;
    2092    if (q == 0) {
    2093      q = nr_digits[x_nr_bits - 1].digits1;
    2094      if (C1 >= nr_digits[x_nr_bits - 1].threshold_lo)
    2095        q++;
    2096    }
    2097    exp = x_exp - 398;	// unbiased exponent
    2098  
    2099    if ((q + exp) > 20) {	// x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
    2100      // set invalid flag
    2101      *pfpsf |= INVALID_EXCEPTION;
    2102      // return Integer Indefinite
    2103      res = 0x8000000000000000ull;
    2104      BID_RETURN (res);
    2105    } else if ((q + exp) == 20) {	// x = c(0)c(1)...c(19).c(20)...c(q-1)
    2106      // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
    2107      // so x rounded to an integer may or may not fit in an unsigned 64-bit int
    2108      // the cases that do not fit are identified here; the ones that fit
    2109      // fall through and will be handled with other cases further,
    2110      // under '1 <= q + exp <= 20'
    2111      if (x_sign) {	// if n < 0 and q + exp = 20 then x is much less than -1/2
    2112        // => set invalid flag
    2113        *pfpsf |= INVALID_EXCEPTION;
    2114        // return Integer Indefinite
    2115        res = 0x8000000000000000ull;
    2116        BID_RETURN (res);
    2117      } else {	// if n > 0 and q + exp = 20
    2118        // if n >= 2^64 - 1/2 then n is too large
    2119        // <=> c(0)c(1)...c(19).c(20)...c(q-1) >= 2^64-1/2
    2120        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 >= 2^64-1/2
    2121        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 >= 5*(2^65-1)
    2122        // <=> C * 10^(21-q) >= 0x9fffffffffffffffb, 1<=q<=16
    2123        if (q == 1) {
    2124  	// C * 10^20 >= 0x9fffffffffffffffb
    2125  	__mul_128x64_to_128 (C, C1, ten2k128[0]);	// 10^20 * C
    2126  	if (C.w[1] > 0x09 ||
    2127  	    (C.w[1] == 0x09 && C.w[0] >= 0xfffffffffffffffbull)) {
    2128  	  // set invalid flag
    2129  	  *pfpsf |= INVALID_EXCEPTION;
    2130  	  // return Integer Indefinite
    2131  	  res = 0x8000000000000000ull;
    2132  	  BID_RETURN (res);
    2133  	}
    2134  	// else cases that can be rounded to a 64-bit int fall through
    2135  	// to '1 <= q + exp <= 20'
    2136        } else {	// if (2 <= q <= 16) => 5 <= 21 - q <= 19
    2137  	// Note: C * 10^(21-q) has 20 or 21 digits; 0x9fffffffffffffffb 
    2138  	// has 21 digits
    2139  	__mul_64x64_to_128MACH (C, C1, ten2k64[21 - q]);
    2140  	if (C.w[1] > 0x09 ||
    2141  	    (C.w[1] == 0x09 && C.w[0] >= 0xfffffffffffffffbull)) {
    2142  	  // set invalid flag
    2143  	  *pfpsf |= INVALID_EXCEPTION;
    2144  	  // return Integer Indefinite
    2145  	  res = 0x8000000000000000ull;
    2146  	  BID_RETURN (res);
    2147  	}
    2148  	// else cases that can be rounded to a 64-bit int fall through
    2149  	// to '1 <= q + exp <= 20'
    2150        }
    2151      }
    2152    }
    2153    // n is not too large to be converted to int64 if -1/2 <= n < 2^64 - 1/2
    2154    // Note: some of the cases tested for above fall through to this point
    2155    if ((q + exp) < 0) {	// n = +/-0.0...c(0)c(1)...c(q-1)
    2156      // set inexact flag
    2157      *pfpsf |= INEXACT_EXCEPTION;
    2158      // return 0
    2159      res = 0x0000000000000000ull;
    2160      BID_RETURN (res);
    2161    } else if ((q + exp) == 0) {	// n = +/-0.c(0)c(1)...c(q-1)
    2162      // if 0.c(0)c(1)...c(q-1) < 0.5 <=> c(0)c(1)...c(q-1) < 5 * 10^(q-1)
    2163      //   res = 0
    2164      // else if x > 0
    2165      //   res = +1
    2166      // else // if x < 0
    2167      //   invalid exc
    2168      ind = q - 1;	// 0 <= ind <= 15
    2169      if (C1 < midpoint64[ind]) {
    2170        res = 0x0000000000000000ull;	// return 0
    2171      } else if (!x_sign) {	// n > 0
    2172        res = 0x0000000000000001ull;	// return +1
    2173      } else {	// if n < 0
    2174        res = 0x8000000000000000ull;
    2175        *pfpsf |= INVALID_EXCEPTION;
    2176        BID_RETURN (res);
    2177      }
    2178      // set inexact flag
    2179      *pfpsf |= INEXACT_EXCEPTION;
    2180    } else {	// if (1 <= q + exp <= 20, 1 <= q <= 16, -15 <= exp <= 19)
    2181      // x <= -1 or 1 <= x < 2^64-1/2 so if positive x can be rounded
    2182      // to nearest to a 64-bit unsigned signed integer
    2183      if (x_sign) {	// x <= -1
    2184        // set invalid flag
    2185        *pfpsf |= INVALID_EXCEPTION;
    2186        // return Integer Indefinite
    2187        res = 0x8000000000000000ull;
    2188        BID_RETURN (res);
    2189      }
    2190      // 1 <= x < 2^64-1/2 so x can be rounded
    2191      // to nearest to a 64-bit unsigned integer
    2192      if (exp < 0) {	// 2 <= q <= 16, -15 <= exp <= -1, 1 <= q + exp <= 20
    2193        ind = -exp;	// 1 <= ind <= 15; ind is a synonym for 'x'
    2194        // chop off ind digits from the lower part of C1
    2195        // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 64 bits
    2196        C1 = C1 + midpoint64[ind - 1];
    2197        // calculate C* and f*
    2198        // C* is actually floor(C*) in this case
    2199        // C* and f* need shifting and masking, as shown by
    2200        // shiftright128[] and maskhigh128[]
    2201        // 1 <= x <= 15 
    2202        // kx = 10^(-x) = ten2mk64[ind - 1]
    2203        // C* = (C1 + 1/2 * 10^x) * 10^(-x)
    2204        // the approximation of 10^(-x) was rounded up to 54 bits
    2205        __mul_64x64_to_128MACH (P128, C1, ten2mk64[ind - 1]);
    2206        Cstar = P128.w[1];
    2207        fstar.w[1] = P128.w[1] & maskhigh128[ind - 1];
    2208        fstar.w[0] = P128.w[0];
    2209        // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind].w[0], e.g.
    2210        // if x=1, T*=ten2mk128trunc[0].w[0]=0x1999999999999999
    2211        // if (0 < f* < 10^(-x)) then the result is a midpoint
    2212        //   if floor(C*) is even then C* = floor(C*) - logical right
    2213        //       shift; C* has p decimal digits, correct by Prop. 1)
    2214        //   else if floor(C*) is odd C* = floor(C*)-1 (logical right
    2215        //       shift; C* has p decimal digits, correct by Pr. 1)
    2216        // else
    2217        //   C* = floor(C*) (logical right shift; C has p decimal digits,
    2218        //       correct by Property 1)
    2219        // n = C* * 10^(e+x)
    2220  
    2221        // shift right C* by Ex-64 = shiftright128[ind]
    2222        shift = shiftright128[ind - 1];	// 0 <= shift <= 39
    2223        Cstar = Cstar >> shift;
    2224        // determine inexactness of the rounding of C*
    2225        // if (0 < f* - 1/2 < 10^(-x)) then
    2226        //   the result is exact
    2227        // else // if (f* - 1/2 > T*) then
    2228        //   the result is inexact
    2229        if (ind - 1 <= 2) {	// fstar.w[1] is 0
    2230  	if (fstar.w[0] > 0x8000000000000000ull) {
    2231  	  // f* > 1/2 and the result may be exact
    2232  	  tmp64 = fstar.w[0] - 0x8000000000000000ull;	// f* - 1/2
    2233  	  if ((tmp64 > ten2mk128trunc[ind - 1].w[1])) {
    2234  	    // ten2mk128trunc[ind -1].w[1] is identical to
    2235  	    // ten2mk128[ind -1].w[1]
    2236  	    // set the inexact flag
    2237  	    *pfpsf |= INEXACT_EXCEPTION;
    2238  	  }	// else the result is exact
    2239  	} else {	// the result is inexact; f2* <= 1/2
    2240  	  // set the inexact flag
    2241  	  *pfpsf |= INEXACT_EXCEPTION;
    2242  	}
    2243        } else {	// if 3 <= ind - 1 <= 14
    2244  	if (fstar.w[1] > onehalf128[ind - 1] ||
    2245  	    (fstar.w[1] == onehalf128[ind - 1] && fstar.w[0])) {
    2246  	  // f2* > 1/2 and the result may be exact
    2247  	  // Calculate f2* - 1/2
    2248  	  tmp64 = fstar.w[1] - onehalf128[ind - 1];
    2249  	  if (tmp64 || fstar.w[0] > ten2mk128trunc[ind - 1].w[1]) {
    2250  	    // ten2mk128trunc[ind -1].w[1] is identical to
    2251  	    // ten2mk128[ind -1].w[1]
    2252  	    // set the inexact flag
    2253  	    *pfpsf |= INEXACT_EXCEPTION;
    2254  	  }	// else the result is exact
    2255  	} else {	// the result is inexact; f2* <= 1/2
    2256  	  // set the inexact flag
    2257  	  *pfpsf |= INEXACT_EXCEPTION;
    2258  	}
    2259        }
    2260  
    2261        // if the result was a midpoint it was rounded away from zero
    2262        res = Cstar;	// the result is positive
    2263      } else if (exp == 0) {
    2264        // 1 <= q <= 10
    2265        // res = +C (exact)
    2266        res = C1;	// the result is positive
    2267      } else {	// if (exp > 0) => 1 <= exp <= 9, 1 <= q < 9, 2 <= q + exp <= 10
    2268        // res = +C * 10^exp (exact)
    2269        res = C1 * ten2k64[exp];	// the result is positive
    2270      }
    2271    }
    2272    BID_RETURN (res);
    2273  }