(root)/
gcc-13.2.0/
libgcc/
config/
libbid/
bid128_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   *  BID128_to_uint64_rnint
      28   ****************************************************************************/
      29  
      30  BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64,
      31  					  bid128_to_uint64_rnint, x)
      32  
      33       UINT64 res;
      34       UINT64 x_sign;
      35       UINT64 x_exp;
      36       int exp;			// unbiased exponent
      37    // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
      38       UINT64 tmp64;
      39       BID_UI64DOUBLE tmp1;
      40       unsigned int x_nr_bits;
      41       int q, ind, shift;
      42       UINT128 C1, C;
      43       UINT128 Cstar;		// C* represents up to 34 decimal digits ~ 113 bits
      44       UINT256 fstar;
      45       UINT256 P256;
      46  
      47    // unpack x
      48  x_sign = x.w[1] & MASK_SIGN;	// 0 for positive, MASK_SIGN for negative
      49  x_exp = x.w[1] & MASK_EXP;	// biased and shifted left 49 bit positions
      50  C1.w[1] = x.w[1] & MASK_COEFF;
      51  C1.w[0] = x.w[0];
      52  
      53    // check for NaN or Infinity
      54  if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
      55      // x is special
      56  if ((x.w[1] & MASK_NAN) == MASK_NAN) {	// x is NAN
      57    if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {	// x is SNAN
      58      // set invalid flag
      59      *pfpsf |= INVALID_EXCEPTION;
      60      // return Integer Indefinite
      61      res = 0x8000000000000000ull;
      62    } else {	// x is QNaN
      63      // set invalid flag
      64      *pfpsf |= INVALID_EXCEPTION;
      65      // return Integer Indefinite
      66      res = 0x8000000000000000ull;
      67    }
      68    BID_RETURN (res);
      69  } else {	// x is not a NaN, so it must be infinity
      70    if (!x_sign) {	// x is +inf
      71      // set invalid flag
      72      *pfpsf |= INVALID_EXCEPTION;
      73      // return Integer Indefinite
      74      res = 0x8000000000000000ull;
      75    } else {	// x is -inf
      76      // set invalid flag
      77      *pfpsf |= INVALID_EXCEPTION;
      78      // return Integer Indefinite
      79      res = 0x8000000000000000ull;
      80    }
      81    BID_RETURN (res);
      82  }
      83  }
      84    // check for non-canonical values (after the check for special values)
      85  if ((C1.w[1] > 0x0001ed09bead87c0ull)
      86      || (C1.w[1] == 0x0001ed09bead87c0ull
      87  	&& (C1.w[0] > 0x378d8e63ffffffffull))
      88      || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
      89    res = 0x0000000000000000ull;
      90    BID_RETURN (res);
      91  } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
      92    // x is 0
      93    res = 0x0000000000000000ull;
      94    BID_RETURN (res);
      95  } else {	// x is not special and is not zero
      96  
      97    // q = nr. of decimal digits in x
      98    //  determine first the nr. of bits in x
      99    if (C1.w[1] == 0) {
     100      if (C1.w[0] >= 0x0020000000000000ull) {	// x >= 2^53
     101        // split the 64-bit value in two 32-bit halves to avoid rounding errors
     102        if (C1.w[0] >= 0x0000000100000000ull) {	// x >= 2^32
     103  	tmp1.d = (double) (C1.w[0] >> 32);	// exact conversion
     104  	x_nr_bits =
     105  	  33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     106        } else {	// x < 2^32
     107  	tmp1.d = (double) (C1.w[0]);	// exact conversion
     108  	x_nr_bits =
     109  	  1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     110        }
     111      } else {	// if x < 2^53
     112        tmp1.d = (double) C1.w[0];	// exact conversion
     113        x_nr_bits =
     114  	1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     115      }
     116    } else {	// C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
     117      tmp1.d = (double) C1.w[1];	// exact conversion
     118      x_nr_bits =
     119        65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     120    }
     121    q = nr_digits[x_nr_bits - 1].digits;
     122    if (q == 0) {
     123      q = nr_digits[x_nr_bits - 1].digits1;
     124      if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
     125  	|| (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi
     126  	    && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
     127        q++;
     128    }
     129    exp = (x_exp >> 49) - 6176;
     130  
     131    if ((q + exp) > 20) {	// x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
     132      // set invalid flag
     133      *pfpsf |= INVALID_EXCEPTION;
     134      // return Integer Indefinite
     135      res = 0x8000000000000000ull;
     136      BID_RETURN (res);
     137    } else if ((q + exp) == 20) {	// x = c(0)c(1)...c(19).c(20)...c(q-1)
     138      // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
     139      // so x rounded to an integer may or may not fit in an unsigned 64-bit int
     140      // the cases that do not fit are identified here; the ones that fit
     141      // fall through and will be handled with other cases further,
     142      // under '1 <= q + exp <= 20'
     143      if (x_sign) {	// if n < 0 and q + exp = 20
     144        // if n < -1/2 then n cannot be converted to uint64 with RN
     145        // too large if c(0)c(1)...c(19).c(20)...c(q-1) > 1/2
     146        // <=> 0.c(0)c(1)...c(q-1) * 10^21 > 0x05, 1<=q<=34
     147        // <=> C * 10^(21-q) > 0x05, 1<=q<=34
     148        if (q == 21) {
     149  	// C > 5 
     150  	if (C1.w[1] != 0 || C1.w[0] > 0x05ull) {
     151  	  // set invalid flag
     152  	  *pfpsf |= INVALID_EXCEPTION;
     153  	  // return Integer Indefinite
     154  	  res = 0x8000000000000000ull;
     155  	  BID_RETURN (res);
     156  	}
     157  	// else cases that can be rounded to 64-bit unsigned int fall through
     158  	// to '1 <= q + exp <= 20'
     159        } else {
     160  	// if 1 <= q <= 20
     161  	//   C * 10^(21-q) > 5 is true because C >= 1 and 10^(21-q) >= 10
     162  	// if 22 <= q <= 34 => 1 <= q - 21 <= 13
     163  	//   C > 5 * 10^(q-21) is true because C > 2^64 and 5*10^(q-21) < 2^64
     164  	// set invalid flag
     165  	*pfpsf |= INVALID_EXCEPTION;
     166  	// return Integer Indefinite
     167  	res = 0x8000000000000000ull;
     168  	BID_RETURN (res);
     169        }
     170      } else {	// if n > 0 and q + exp = 20
     171        // if n >= 2^64 - 1/2 then n is too large
     172        // <=> c(0)c(1)...c(19).c(20)...c(q-1) >= 2^64-1/2
     173        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 >= 2^64-1/2
     174        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 >= 5*(2^65-1)
     175        // <=> C * 10^(21-q) >= 0x9fffffffffffffffb, 1<=q<=34
     176        if (q == 1) {
     177  	// C * 10^20 >= 0x9fffffffffffffffb
     178  	__mul_128x64_to_128 (C, C1.w[0], ten2k128[0]);	// 10^20 * C
     179  	if (C.w[1] > 0x09 || (C.w[1] == 0x09
     180  			      && C.w[0] >= 0xfffffffffffffffbull)) {
     181  	  // set invalid flag
     182  	  *pfpsf |= INVALID_EXCEPTION;
     183  	  // return Integer Indefinite
     184  	  res = 0x8000000000000000ull;
     185  	  BID_RETURN (res);
     186  	}
     187  	// else cases that can be rounded to a 64-bit int fall through
     188  	// to '1 <= q + exp <= 20'
     189        } else if (q <= 19) {
     190  	// C * 10^(21-q) >= 0x9fffffffffffffffb
     191  	__mul_64x64_to_128MACH (C, C1.w[0], ten2k64[21 - q]);
     192  	if (C.w[1] > 0x09 || (C.w[1] == 0x09
     193  			      && C.w[0] >= 0xfffffffffffffffbull)) {
     194  	  // set invalid flag
     195  	  *pfpsf |= INVALID_EXCEPTION;
     196  	  // return Integer Indefinite
     197  	  res = 0x8000000000000000ull;
     198  	  BID_RETURN (res);
     199  	}
     200  	// else cases that can be rounded to a 64-bit int fall through
     201  	// to '1 <= q + exp <= 20'
     202        } else if (q == 20) {
     203  	// C * 10 >= 0x9fffffffffffffffb <=> C * 2 > 1ffffffffffffffff
     204  	C.w[0] = C1.w[0] + C1.w[0];
     205  	C.w[1] = C1.w[1] + C1.w[1];
     206  	if (C.w[0] < C1.w[0])
     207  	  C.w[1]++;
     208  	if (C.w[1] > 0x01 || (C.w[1] == 0x01
     209  			      && C.w[0] >= 0xffffffffffffffffull)) {
     210  	  // set invalid flag
     211  	  *pfpsf |= INVALID_EXCEPTION;
     212  	  // return Integer Indefinite
     213  	  res = 0x8000000000000000ull;
     214  	  BID_RETURN (res);
     215  	}
     216  	// else cases that can be rounded to a 64-bit int fall through
     217  	// to '1 <= q + exp <= 20'
     218        } else if (q == 21) {
     219  	// C >= 0x9fffffffffffffffb
     220  	if (C1.w[1] > 0x09 || (C1.w[1] == 0x09
     221  			       && C1.w[0] >= 0xfffffffffffffffbull)) {
     222  	  // set invalid flag
     223  	  *pfpsf |= INVALID_EXCEPTION;
     224  	  // return Integer Indefinite
     225  	  res = 0x8000000000000000ull;
     226  	  BID_RETURN (res);
     227  	}
     228  	// else cases that can be rounded to a 64-bit int fall through
     229  	// to '1 <= q + exp <= 20'
     230        } else {	// if 22 <= q <= 34 => 1 <= q - 21 <= 13
     231  	// C  >= 10^(q-21) * 0x9fffffffffffffffb max 44 bits x 68 bits
     232  	C.w[1] = 0x09;
     233  	C.w[0] = 0xfffffffffffffffbull;
     234  	__mul_128x64_to_128 (C, ten2k64[q - 21], C);
     235  	if (C1.w[1] > C.w[1]
     236  	    || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) {
     237  	  // set invalid flag
     238  	  *pfpsf |= INVALID_EXCEPTION;
     239  	  // return Integer Indefinite
     240  	  res = 0x8000000000000000ull;
     241  	  BID_RETURN (res);
     242  	}
     243  	// else cases that can be rounded to a 64-bit int fall through
     244  	// to '1 <= q + exp <= 20'
     245        }
     246      }
     247    }
     248    // n is not too large to be converted to int64 if -1/2 <= n < 2^64 - 1/2
     249    // Note: some of the cases tested for above fall through to this point
     250    if ((q + exp) < 0) {	// n = +/-0.0...c(0)c(1)...c(q-1)
     251      // return 0
     252      res = 0x0000000000000000ull;
     253      BID_RETURN (res);
     254    } else if ((q + exp) == 0) {	// n = +/-0.c(0)c(1)...c(q-1)
     255      // if 0.c(0)c(1)...c(q-1) <= 0.5 <=> c(0)c(1)...c(q-1) <= 5 * 10^(q-1)
     256      //   res = 0
     257      // else if x > 0
     258      //   res = +1
     259      // else // if x < 0
     260      //   invalid exc
     261      ind = q - 1;
     262      if (ind <= 18) {	// 0 <= ind <= 18
     263        if ((C1.w[1] == 0) && (C1.w[0] <= midpoint64[ind])) {
     264  	res = 0x0000000000000000ull;	// return 0
     265        } else if (!x_sign) {	// n > 0
     266  	res = 0x00000001;	// return +1
     267        } else {
     268  	res = 0x8000000000000000ull;
     269  	*pfpsf |= INVALID_EXCEPTION;
     270        }
     271      } else {	// 19 <= ind <= 33
     272        if ((C1.w[1] < midpoint128[ind - 19].w[1])
     273  	  || ((C1.w[1] == midpoint128[ind - 19].w[1])
     274  	      && (C1.w[0] <= midpoint128[ind - 19].w[0]))) {
     275  	res = 0x0000000000000000ull;	// return 0
     276        } else if (!x_sign) {	// n > 0
     277  	res = 0x00000001;	// return +1
     278        } else {
     279  	res = 0x8000000000000000ull;
     280  	*pfpsf |= INVALID_EXCEPTION;
     281        }
     282      }
     283    } else {	// if (1 <= q + exp <= 20, 1 <= q <= 34, -33 <= exp <= 19)
     284      // x <= -1 or 1 <= x < 2^64-1/2 so if positive x can be rounded
     285      // to nearest to a 64-bit unsigned signed integer
     286      if (x_sign) {	// x <= -1
     287        // set invalid flag
     288        *pfpsf |= INVALID_EXCEPTION;
     289        // return Integer Indefinite
     290        res = 0x8000000000000000ull;
     291        BID_RETURN (res);
     292      }
     293      // 1 <= x < 2^64-1/2 so x can be rounded
     294      // to nearest to a 64-bit unsigned integer
     295      if (exp < 0) {	// 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 20
     296        ind = -exp;	// 1 <= ind <= 33; ind is a synonym for 'x'
     297        // chop off ind digits from the lower part of C1
     298        // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 127 bits
     299        tmp64 = C1.w[0];
     300        if (ind <= 19) {
     301  	C1.w[0] = C1.w[0] + midpoint64[ind - 1];
     302        } else {
     303  	C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
     304  	C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
     305        }
     306        if (C1.w[0] < tmp64)
     307  	C1.w[1]++;
     308        // calculate C* and f*
     309        // C* is actually floor(C*) in this case
     310        // C* and f* need shifting and masking, as shown by
     311        // shiftright128[] and maskhigh128[]
     312        // 1 <= x <= 33
     313        // kx = 10^(-x) = ten2mk128[ind - 1]
     314        // C* = (C1 + 1/2 * 10^x) * 10^(-x)
     315        // the approximation of 10^(-x) was rounded up to 118 bits
     316        __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
     317        if (ind - 1 <= 21) {	// 0 <= ind - 1 <= 21
     318  	Cstar.w[1] = P256.w[3];
     319  	Cstar.w[0] = P256.w[2];
     320  	fstar.w[3] = 0;
     321  	fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
     322  	fstar.w[1] = P256.w[1];
     323  	fstar.w[0] = P256.w[0];
     324        } else {	// 22 <= ind - 1 <= 33
     325  	Cstar.w[1] = 0;
     326  	Cstar.w[0] = P256.w[3];
     327  	fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
     328  	fstar.w[2] = P256.w[2];
     329  	fstar.w[1] = P256.w[1];
     330  	fstar.w[0] = P256.w[0];
     331        }
     332        // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
     333        // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
     334        // if (0 < f* < 10^(-x)) then the result is a midpoint
     335        //   if floor(C*) is even then C* = floor(C*) - logical right
     336        //       shift; C* has p decimal digits, correct by Prop. 1)
     337        //   else if floor(C*) is odd C* = floor(C*)-1 (logical right
     338        //       shift; C* has p decimal digits, correct by Pr. 1)
     339        // else
     340        //   C* = floor(C*) (logical right shift; C has p decimal digits,
     341        //       correct by Property 1)
     342        // n = C* * 10^(e+x)
     343  
     344        // shift right C* by Ex-128 = shiftright128[ind]
     345        shift = shiftright128[ind - 1];	// 0 <= shift <= 102
     346        if (ind - 1 <= 21) {	// 0 <= ind - 1 <= 21
     347  	Cstar.w[0] =
     348  	  (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift));
     349  	// redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
     350        } else {	// 22 <= ind - 1 <= 33
     351  	Cstar.w[0] = (Cstar.w[0] >> (shift - 64));	// 2 <= shift - 64 <= 38
     352        }
     353        // if the result was a midpoint it was rounded away from zero, so
     354        // it will need a correction
     355        // check for midpoints
     356        if ((fstar.w[3] == 0) && (fstar.w[2] == 0)
     357  	  && (fstar.w[1] || fstar.w[0])
     358  	  && (fstar.w[1] < ten2mk128trunc[ind - 1].w[1]
     359  	      || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
     360  		  && fstar.w[0] <= ten2mk128trunc[ind - 1].w[0]))) {
     361  	// the result is a midpoint; round to nearest
     362  	if (Cstar.w[0] & 0x01) {	// Cstar.w[0] is odd; MP in [EVEN, ODD]
     363  	  // if floor(C*) is odd C = floor(C*) - 1; the result >= 1
     364  	  Cstar.w[0]--;	// Cstar.w[0] is now even
     365  	}	// else MP in [ODD, EVEN]
     366        }
     367        res = Cstar.w[0];	// the result is positive
     368      } else if (exp == 0) {
     369        // 1 <= q <= 20, but x < 2^64 - 1/2 so in this case C1.w[1] has to be 0
     370        // res = C (exact)
     371        res = C1.w[0];
     372      } else {
     373        // if (exp > 0) => 1 <= exp <= 19, 1 <= q < 19, 2 <= q + exp <= 20
     374        // res = C * 10^exp (exact) - must fit in 64 bits
     375        res = C1.w[0] * ten2k64[exp];
     376      }
     377    }
     378  }
     379  
     380  BID_RETURN (res);
     381  }
     382  
     383  /*****************************************************************************
     384   *  BID128_to_uint64_xrnint
     385   ****************************************************************************/
     386  
     387  BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64,
     388  					  bid128_to_uint64_xrnint, x)
     389  
     390       UINT64 res;
     391       UINT64 x_sign;
     392       UINT64 x_exp;
     393       int exp;			// unbiased exponent
     394    // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
     395       UINT64 tmp64, tmp64A;
     396       BID_UI64DOUBLE tmp1;
     397       unsigned int x_nr_bits;
     398       int q, ind, shift;
     399       UINT128 C1, C;
     400       UINT128 Cstar;		// C* represents up to 34 decimal digits ~ 113 bits
     401       UINT256 fstar;
     402       UINT256 P256;
     403  
     404    // unpack x
     405  x_sign = x.w[1] & MASK_SIGN;	// 0 for positive, MASK_SIGN for negative
     406  x_exp = x.w[1] & MASK_EXP;	// biased and shifted left 49 bit positions
     407  C1.w[1] = x.w[1] & MASK_COEFF;
     408  C1.w[0] = x.w[0];
     409  
     410    // check for NaN or Infinity
     411  if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
     412      // x is special
     413  if ((x.w[1] & MASK_NAN) == MASK_NAN) {	// x is NAN
     414    if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {	// x is SNAN
     415      // set invalid flag
     416      *pfpsf |= INVALID_EXCEPTION;
     417      // return Integer Indefinite
     418      res = 0x8000000000000000ull;
     419    } else {	// x is QNaN
     420      // set invalid flag
     421      *pfpsf |= INVALID_EXCEPTION;
     422      // return Integer Indefinite
     423      res = 0x8000000000000000ull;
     424    }
     425    BID_RETURN (res);
     426  } else {	// x is not a NaN, so it must be infinity
     427    if (!x_sign) {	// x is +inf
     428      // set invalid flag
     429      *pfpsf |= INVALID_EXCEPTION;
     430      // return Integer Indefinite
     431      res = 0x8000000000000000ull;
     432    } else {	// x is -inf
     433      // set invalid flag
     434      *pfpsf |= INVALID_EXCEPTION;
     435      // return Integer Indefinite
     436      res = 0x8000000000000000ull;
     437    }
     438    BID_RETURN (res);
     439  }
     440  }
     441    // check for non-canonical values (after the check for special values)
     442  if ((C1.w[1] > 0x0001ed09bead87c0ull)
     443      || (C1.w[1] == 0x0001ed09bead87c0ull
     444  	&& (C1.w[0] > 0x378d8e63ffffffffull))
     445      || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
     446    res = 0x0000000000000000ull;
     447    BID_RETURN (res);
     448  } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
     449    // x is 0
     450    res = 0x0000000000000000ull;
     451    BID_RETURN (res);
     452  } else {	// x is not special and is not zero
     453  
     454    // q = nr. of decimal digits in x
     455    //  determine first the nr. of bits in x
     456    if (C1.w[1] == 0) {
     457      if (C1.w[0] >= 0x0020000000000000ull) {	// x >= 2^53
     458        // split the 64-bit value in two 32-bit halves to avoid rounding errors
     459        if (C1.w[0] >= 0x0000000100000000ull) {	// x >= 2^32
     460  	tmp1.d = (double) (C1.w[0] >> 32);	// exact conversion
     461  	x_nr_bits =
     462  	  33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     463        } else {	// x < 2^32
     464  	tmp1.d = (double) (C1.w[0]);	// exact conversion
     465  	x_nr_bits =
     466  	  1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     467        }
     468      } else {	// if x < 2^53
     469        tmp1.d = (double) C1.w[0];	// exact conversion
     470        x_nr_bits =
     471  	1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     472      }
     473    } else {	// C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
     474      tmp1.d = (double) C1.w[1];	// exact conversion
     475      x_nr_bits =
     476        65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     477    }
     478    q = nr_digits[x_nr_bits - 1].digits;
     479    if (q == 0) {
     480      q = nr_digits[x_nr_bits - 1].digits1;
     481      if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
     482  	|| (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi
     483  	    && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
     484        q++;
     485    }
     486    exp = (x_exp >> 49) - 6176;
     487  
     488    if ((q + exp) > 20) {	// x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
     489      // set invalid flag
     490      *pfpsf |= INVALID_EXCEPTION;
     491      // return Integer Indefinite
     492      res = 0x8000000000000000ull;
     493      BID_RETURN (res);
     494    } else if ((q + exp) == 20) {	// x = c(0)c(1)...c(19).c(20)...c(q-1)
     495      // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
     496      // so x rounded to an integer may or may not fit in an unsigned 64-bit int
     497      // the cases that do not fit are identified here; the ones that fit
     498      // fall through and will be handled with other cases further,
     499      // under '1 <= q + exp <= 20'
     500      if (x_sign) {	// if n < 0 and q + exp = 20
     501        // if n < -1/2 then n cannot be converted to uint64 with RN
     502        // too large if c(0)c(1)...c(19).c(20)...c(q-1) > 1/2
     503        // <=> 0.c(0)c(1)...c(q-1) * 10^21 > 0x05, 1<=q<=34
     504        // <=> C * 10^(21-q) > 0x05, 1<=q<=34
     505        if (q == 21) {
     506  	// C > 5 
     507  	if (C1.w[1] != 0 || C1.w[0] > 0x05ull) {
     508  	  // set invalid flag
     509  	  *pfpsf |= INVALID_EXCEPTION;
     510  	  // return Integer Indefinite
     511  	  res = 0x8000000000000000ull;
     512  	  BID_RETURN (res);
     513  	}
     514  	// else cases that can be rounded to 64-bit unsigned int fall through
     515  	// to '1 <= q + exp <= 20'
     516        } else {
     517  	// if 1 <= q <= 20
     518  	//   C * 10^(21-q) > 5 is true because C >= 1 and 10^(21-q) >= 10
     519  	// if 22 <= q <= 34 => 1 <= q - 21 <= 13
     520  	//   C > 5 * 10^(q-21) is true because C > 2^64 and 5*10^(q-21) < 2^64
     521  	// set invalid flag
     522  	*pfpsf |= INVALID_EXCEPTION;
     523  	// return Integer Indefinite
     524  	res = 0x8000000000000000ull;
     525  	BID_RETURN (res);
     526        }
     527      } else {	// if n > 0 and q + exp = 20
     528        // if n >= 2^64 - 1/2 then n is too large
     529        // <=> c(0)c(1)...c(19).c(20)...c(q-1) >= 2^64-1/2
     530        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 >= 2^64-1/2
     531        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 >= 5*(2^65-1)
     532        // <=> C * 10^(21-q) >= 0x9fffffffffffffffb, 1<=q<=34
     533        if (q == 1) {
     534  	// C * 10^20 >= 0x9fffffffffffffffb
     535  	__mul_128x64_to_128 (C, C1.w[0], ten2k128[0]);	// 10^20 * C
     536  	if (C.w[1] > 0x09 || (C.w[1] == 0x09
     537  			      && C.w[0] >= 0xfffffffffffffffbull)) {
     538  	  // set invalid flag
     539  	  *pfpsf |= INVALID_EXCEPTION;
     540  	  // return Integer Indefinite
     541  	  res = 0x8000000000000000ull;
     542  	  BID_RETURN (res);
     543  	}
     544  	// else cases that can be rounded to a 64-bit int fall through
     545  	// to '1 <= q + exp <= 20'
     546        } else if (q <= 19) {
     547  	// C * 10^(21-q) >= 0x9fffffffffffffffb
     548  	__mul_64x64_to_128MACH (C, C1.w[0], ten2k64[21 - q]);
     549  	if (C.w[1] > 0x09 || (C.w[1] == 0x09
     550  			      && C.w[0] >= 0xfffffffffffffffbull)) {
     551  	  // set invalid flag
     552  	  *pfpsf |= INVALID_EXCEPTION;
     553  	  // return Integer Indefinite
     554  	  res = 0x8000000000000000ull;
     555  	  BID_RETURN (res);
     556  	}
     557  	// else cases that can be rounded to a 64-bit int fall through
     558  	// to '1 <= q + exp <= 20'
     559        } else if (q == 20) {
     560  	// C * 10 >= 0x9fffffffffffffffb <=> C * 2 > 1ffffffffffffffff
     561  	C.w[0] = C1.w[0] + C1.w[0];
     562  	C.w[1] = C1.w[1] + C1.w[1];
     563  	if (C.w[0] < C1.w[0])
     564  	  C.w[1]++;
     565  	if (C.w[1] > 0x01 || (C.w[1] == 0x01
     566  			      && C.w[0] >= 0xffffffffffffffffull)) {
     567  	  // set invalid flag
     568  	  *pfpsf |= INVALID_EXCEPTION;
     569  	  // return Integer Indefinite
     570  	  res = 0x8000000000000000ull;
     571  	  BID_RETURN (res);
     572  	}
     573  	// else cases that can be rounded to a 64-bit int fall through
     574  	// to '1 <= q + exp <= 20'
     575        } else if (q == 21) {
     576  	// C >= 0x9fffffffffffffffb
     577  	if (C1.w[1] > 0x09 || (C1.w[1] == 0x09
     578  			       && C1.w[0] >= 0xfffffffffffffffbull)) {
     579  	  // set invalid flag
     580  	  *pfpsf |= INVALID_EXCEPTION;
     581  	  // return Integer Indefinite
     582  	  res = 0x8000000000000000ull;
     583  	  BID_RETURN (res);
     584  	}
     585  	// else cases that can be rounded to a 64-bit int fall through
     586  	// to '1 <= q + exp <= 20'
     587        } else {	// if 22 <= q <= 34 => 1 <= q - 21 <= 13
     588  	// C  >= 10^(q-21) * 0x9fffffffffffffffb max 44 bits x 68 bits
     589  	C.w[1] = 0x09;
     590  	C.w[0] = 0xfffffffffffffffbull;
     591  	__mul_128x64_to_128 (C, ten2k64[q - 21], C);
     592  	if (C1.w[1] > C.w[1]
     593  	    || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) {
     594  	  // set invalid flag
     595  	  *pfpsf |= INVALID_EXCEPTION;
     596  	  // return Integer Indefinite
     597  	  res = 0x8000000000000000ull;
     598  	  BID_RETURN (res);
     599  	}
     600  	// else cases that can be rounded to a 64-bit int fall through
     601  	// to '1 <= q + exp <= 20'
     602        }
     603      }
     604    }
     605    // n is not too large to be converted to int64 if -1/2 <= n < 2^64 - 1/2
     606    // Note: some of the cases tested for above fall through to this point
     607    if ((q + exp) < 0) {	// n = +/-0.0...c(0)c(1)...c(q-1)
     608      // set inexact flag
     609      *pfpsf |= INEXACT_EXCEPTION;
     610      // return 0
     611      res = 0x0000000000000000ull;
     612      BID_RETURN (res);
     613    } else if ((q + exp) == 0) {	// n = +/-0.c(0)c(1)...c(q-1)
     614      // if 0.c(0)c(1)...c(q-1) <= 0.5 <=> c(0)c(1)...c(q-1) <= 5 * 10^(q-1)
     615      //   res = 0
     616      // else if x > 0
     617      //   res = +1
     618      // else // if x < 0
     619      //   invalid exc
     620      ind = q - 1;
     621      if (ind <= 18) {	// 0 <= ind <= 18
     622        if ((C1.w[1] == 0) && (C1.w[0] <= midpoint64[ind])) {
     623  	res = 0x0000000000000000ull;	// return 0
     624        } else if (!x_sign) {	// n > 0
     625  	res = 0x00000001;	// return +1
     626        } else {
     627  	res = 0x8000000000000000ull;
     628  	*pfpsf |= INVALID_EXCEPTION;
     629  	BID_RETURN (res);
     630        }
     631      } else {	// 19 <= ind <= 33
     632        if ((C1.w[1] < midpoint128[ind - 19].w[1])
     633  	  || ((C1.w[1] == midpoint128[ind - 19].w[1])
     634  	      && (C1.w[0] <= midpoint128[ind - 19].w[0]))) {
     635  	res = 0x0000000000000000ull;	// return 0
     636        } else if (!x_sign) {	// n > 0
     637  	res = 0x00000001;	// return +1
     638        } else {
     639  	res = 0x8000000000000000ull;
     640  	*pfpsf |= INVALID_EXCEPTION;
     641  	BID_RETURN (res);
     642        }
     643      }
     644      // set inexact flag
     645      *pfpsf |= INEXACT_EXCEPTION;
     646    } else {	// if (1 <= q + exp <= 20, 1 <= q <= 34, -33 <= exp <= 19)
     647      // x <= -1 or 1 <= x < 2^64-1/2 so if positive x can be rounded
     648      // to nearest to a 64-bit unsigned signed integer
     649      if (x_sign) {	// x <= -1
     650        // set invalid flag
     651        *pfpsf |= INVALID_EXCEPTION;
     652        // return Integer Indefinite
     653        res = 0x8000000000000000ull;
     654        BID_RETURN (res);
     655      }
     656      // 1 <= x < 2^64-1/2 so x can be rounded
     657      // to nearest to a 64-bit unsigned integer
     658      if (exp < 0) {	// 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 20
     659        ind = -exp;	// 1 <= ind <= 33; ind is a synonym for 'x'
     660        // chop off ind digits from the lower part of C1
     661        // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 127 bits
     662        tmp64 = C1.w[0];
     663        if (ind <= 19) {
     664  	C1.w[0] = C1.w[0] + midpoint64[ind - 1];
     665        } else {
     666  	C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
     667  	C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
     668        }
     669        if (C1.w[0] < tmp64)
     670  	C1.w[1]++;
     671        // calculate C* and f*
     672        // C* is actually floor(C*) in this case
     673        // C* and f* need shifting and masking, as shown by
     674        // shiftright128[] and maskhigh128[]
     675        // 1 <= x <= 33
     676        // kx = 10^(-x) = ten2mk128[ind - 1]
     677        // C* = (C1 + 1/2 * 10^x) * 10^(-x)
     678        // the approximation of 10^(-x) was rounded up to 118 bits
     679        __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
     680        if (ind - 1 <= 21) {	// 0 <= ind - 1 <= 21
     681  	Cstar.w[1] = P256.w[3];
     682  	Cstar.w[0] = P256.w[2];
     683  	fstar.w[3] = 0;
     684  	fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
     685  	fstar.w[1] = P256.w[1];
     686  	fstar.w[0] = P256.w[0];
     687        } else {	// 22 <= ind - 1 <= 33
     688  	Cstar.w[1] = 0;
     689  	Cstar.w[0] = P256.w[3];
     690  	fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
     691  	fstar.w[2] = P256.w[2];
     692  	fstar.w[1] = P256.w[1];
     693  	fstar.w[0] = P256.w[0];
     694        }
     695        // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
     696        // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
     697        // if (0 < f* < 10^(-x)) then the result is a midpoint
     698        //   if floor(C*) is even then C* = floor(C*) - logical right
     699        //       shift; C* has p decimal digits, correct by Prop. 1)
     700        //   else if floor(C*) is odd C* = floor(C*)-1 (logical right
     701        //       shift; C* has p decimal digits, correct by Pr. 1)
     702        // else
     703        //   C* = floor(C*) (logical right shift; C has p decimal digits,
     704        //       correct by Property 1)
     705        // n = C* * 10^(e+x)
     706  
     707        // shift right C* by Ex-128 = shiftright128[ind]
     708        shift = shiftright128[ind - 1];	// 0 <= shift <= 102
     709        if (ind - 1 <= 21) {	// 0 <= ind - 1 <= 21
     710  	Cstar.w[0] =
     711  	  (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift));
     712  	// redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
     713        } else {	// 22 <= ind - 1 <= 33
     714  	Cstar.w[0] = (Cstar.w[0] >> (shift - 64));	// 2 <= shift - 64 <= 38
     715        }
     716        // determine inexactness of the rounding of C*
     717        // if (0 < f* - 1/2 < 10^(-x)) then
     718        //   the result is exact
     719        // else // if (f* - 1/2 > T*) then
     720        //   the result is inexact
     721        if (ind - 1 <= 2) {
     722  	if (fstar.w[1] > 0x8000000000000000ull ||
     723  	    (fstar.w[1] == 0x8000000000000000ull
     724  	     && fstar.w[0] > 0x0ull)) {
     725  	  // f* > 1/2 and the result may be exact
     726  	  tmp64 = fstar.w[1] - 0x8000000000000000ull;	// f* - 1/2
     727  	  if (tmp64 > ten2mk128trunc[ind - 1].w[1]
     728  	      || (tmp64 == ten2mk128trunc[ind - 1].w[1]
     729  		  && fstar.w[0] >= ten2mk128trunc[ind - 1].w[0])) {
     730  	    // set the inexact flag
     731  	    *pfpsf |= INEXACT_EXCEPTION;
     732  	  }	// else the result is exact
     733  	} else {	// the result is inexact; f2* <= 1/2
     734  	  // set the inexact flag
     735  	  *pfpsf |= INEXACT_EXCEPTION;
     736  	}
     737        } else if (ind - 1 <= 21) {	// if 3 <= ind <= 21
     738  	if (fstar.w[3] > 0x0 ||
     739  	    (fstar.w[3] == 0x0 && fstar.w[2] > onehalf128[ind - 1]) ||
     740  	    (fstar.w[3] == 0x0 && fstar.w[2] == onehalf128[ind - 1] &&
     741  	     (fstar.w[1] || fstar.w[0]))) {
     742  	  // f2* > 1/2 and the result may be exact
     743  	  // Calculate f2* - 1/2
     744  	  tmp64 = fstar.w[2] - onehalf128[ind - 1];
     745  	  tmp64A = fstar.w[3];
     746  	  if (tmp64 > fstar.w[2])
     747  	    tmp64A--;
     748  	  if (tmp64A || tmp64
     749  	      || fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
     750  	      || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
     751  		  && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
     752  	    // set the inexact flag
     753  	    *pfpsf |= INEXACT_EXCEPTION;
     754  	  }	// else the result is exact
     755  	} else {	// the result is inexact; f2* <= 1/2
     756  	  // set the inexact flag
     757  	  *pfpsf |= INEXACT_EXCEPTION;
     758  	}
     759        } else {	// if 22 <= ind <= 33
     760  	if (fstar.w[3] > onehalf128[ind - 1] ||
     761  	    (fstar.w[3] == onehalf128[ind - 1] &&
     762  	     (fstar.w[2] || fstar.w[1] || fstar.w[0]))) {
     763  	  // f2* > 1/2 and the result may be exact
     764  	  // Calculate f2* - 1/2
     765  	  tmp64 = fstar.w[3] - onehalf128[ind - 1];
     766  	  if (tmp64 || fstar.w[2]
     767  	      || fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
     768  	      || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
     769  		  && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
     770  	    // set the inexact flag
     771  	    *pfpsf |= INEXACT_EXCEPTION;
     772  	  }	// else the result is exact
     773  	} else {	// the result is inexact; f2* <= 1/2
     774  	  // set the inexact flag
     775  	  *pfpsf |= INEXACT_EXCEPTION;
     776  	}
     777        }
     778  
     779        // if the result was a midpoint it was rounded away from zero, so
     780        // it will need a correction
     781        // check for midpoints
     782        if ((fstar.w[3] == 0) && (fstar.w[2] == 0)
     783  	  && (fstar.w[1] || fstar.w[0])
     784  	  && (fstar.w[1] < ten2mk128trunc[ind - 1].w[1]
     785  	      || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
     786  		  && fstar.w[0] <= ten2mk128trunc[ind - 1].w[0]))) {
     787  	// the result is a midpoint; round to nearest
     788  	if (Cstar.w[0] & 0x01) {	// Cstar.w[0] is odd; MP in [EVEN, ODD]
     789  	  // if floor(C*) is odd C = floor(C*) - 1; the result >= 1
     790  	  Cstar.w[0]--;	// Cstar.w[0] is now even
     791  	}	// else MP in [ODD, EVEN]
     792        }
     793        res = Cstar.w[0];	// the result is positive
     794      } else if (exp == 0) {
     795        // 1 <= q <= 20, but x < 2^64 - 1/2 so in this case C1.w[1] has to be 0
     796        // res = C (exact)
     797        res = C1.w[0];
     798      } else {
     799        // if (exp > 0) => 1 <= exp <= 19, 1 <= q < 19, 2 <= q + exp <= 20
     800        // res = C * 10^exp (exact) - must fit in 64 bits
     801        res = C1.w[0] * ten2k64[exp];
     802      }
     803    }
     804  }
     805  
     806  BID_RETURN (res);
     807  }
     808  
     809  /*****************************************************************************
     810   *  BID128_to_uint64_floor
     811   ****************************************************************************/
     812  
     813  BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64,
     814  					  bid128_to_uint64_floor, x)
     815  
     816       UINT64 res;
     817       UINT64 x_sign;
     818       UINT64 x_exp;
     819       int exp;			// unbiased exponent
     820    // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
     821       BID_UI64DOUBLE tmp1;
     822       unsigned int x_nr_bits;
     823       int q, ind, shift;
     824       UINT128 C1, C;
     825       UINT128 Cstar;		// C* represents up to 34 decimal digits ~ 113 bits
     826       UINT256 P256;
     827  
     828    // unpack x
     829  x_sign = x.w[1] & MASK_SIGN;	// 0 for positive, MASK_SIGN for negative
     830  x_exp = x.w[1] & MASK_EXP;	// biased and shifted left 49 bit positions
     831  C1.w[1] = x.w[1] & MASK_COEFF;
     832  C1.w[0] = x.w[0];
     833  
     834    // check for NaN or Infinity
     835  if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
     836      // x is special
     837  if ((x.w[1] & MASK_NAN) == MASK_NAN) {	// x is NAN
     838    if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {	// x is SNAN
     839      // set invalid flag
     840      *pfpsf |= INVALID_EXCEPTION;
     841      // return Integer Indefinite
     842      res = 0x8000000000000000ull;
     843    } else {	// x is QNaN
     844      // set invalid flag
     845      *pfpsf |= INVALID_EXCEPTION;
     846      // return Integer Indefinite
     847      res = 0x8000000000000000ull;
     848    }
     849    BID_RETURN (res);
     850  } else {	// x is not a NaN, so it must be infinity
     851    if (!x_sign) {	// x is +inf
     852      // set invalid flag
     853      *pfpsf |= INVALID_EXCEPTION;
     854      // return Integer Indefinite
     855      res = 0x8000000000000000ull;
     856    } else {	// x is -inf
     857      // set invalid flag
     858      *pfpsf |= INVALID_EXCEPTION;
     859      // return Integer Indefinite
     860      res = 0x8000000000000000ull;
     861    }
     862    BID_RETURN (res);
     863  }
     864  }
     865    // check for non-canonical values (after the check for special values)
     866  if ((C1.w[1] > 0x0001ed09bead87c0ull)
     867      || (C1.w[1] == 0x0001ed09bead87c0ull
     868  	&& (C1.w[0] > 0x378d8e63ffffffffull))
     869      || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
     870    res = 0x0000000000000000ull;
     871    BID_RETURN (res);
     872  } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
     873    // x is 0
     874    res = 0x0000000000000000ull;
     875    BID_RETURN (res);
     876  } else {	// x is not special and is not zero
     877  
     878    // if n < 0 then n cannot be converted to uint64 with RM
     879    if (x_sign) {	// if n < 0 and q + exp = 20
     880      // too large if c(0)c(1)...c(19).c(20)...c(q-1) > 0
     881      // set invalid flag
     882      *pfpsf |= INVALID_EXCEPTION;
     883      // return Integer Indefinite
     884      res = 0x8000000000000000ull;
     885      BID_RETURN (res);
     886    }
     887    // q = nr. of decimal digits in x
     888    //  determine first the nr. of bits in x
     889    if (C1.w[1] == 0) {
     890      if (C1.w[0] >= 0x0020000000000000ull) {	// x >= 2^53
     891        // split the 64-bit value in two 32-bit halves to avoid rounding errors
     892        if (C1.w[0] >= 0x0000000100000000ull) {	// x >= 2^32
     893  	tmp1.d = (double) (C1.w[0] >> 32);	// exact conversion
     894  	x_nr_bits =
     895  	  33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     896        } else {	// x < 2^32
     897  	tmp1.d = (double) (C1.w[0]);	// exact conversion
     898  	x_nr_bits =
     899  	  1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     900        }
     901      } else {	// if x < 2^53
     902        tmp1.d = (double) C1.w[0];	// exact conversion
     903        x_nr_bits =
     904  	1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     905      }
     906    } else {	// C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
     907      tmp1.d = (double) C1.w[1];	// exact conversion
     908      x_nr_bits =
     909        65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     910    }
     911    q = nr_digits[x_nr_bits - 1].digits;
     912    if (q == 0) {
     913      q = nr_digits[x_nr_bits - 1].digits1;
     914      if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
     915  	|| (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi
     916  	    && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
     917        q++;
     918    }
     919    exp = (x_exp >> 49) - 6176;
     920    if ((q + exp) > 20) {	// x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
     921      // set invalid flag
     922      *pfpsf |= INVALID_EXCEPTION;
     923      // return Integer Indefinite
     924      res = 0x8000000000000000ull;
     925      BID_RETURN (res);
     926    } else if ((q + exp) == 20) {	// x = c(0)c(1)...c(19).c(20)...c(q-1)
     927      // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
     928      // so x rounded to an integer may or may not fit in an unsigned 64-bit int
     929      // the cases that do not fit are identified here; the ones that fit
     930      // fall through and will be handled with other cases further,
     931      // under '1 <= q + exp <= 20'
     932      // if n > 0 and q + exp = 20
     933      // if n >= 2^64 then n is too large
     934      // <=> c(0)c(1)...c(19).c(20)...c(q-1) >= 2^64
     935      // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 >= 2^64
     936      // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 >= 5*2^65
     937      // <=> C * 10^(21-q) >= 0xa0000000000000000, 1<=q<=34
     938      if (q == 1) {
     939        // C * 10^20 >= 0xa0000000000000000
     940        __mul_128x64_to_128 (C, C1.w[0], ten2k128[0]);	// 10^20 * C
     941        if (C.w[1] >= 0x0a) {
     942  	// actually C.w[1] == 0x0a && C.w[0] >= 0x0000000000000000ull) {
     943  	// set invalid flag
     944  	*pfpsf |= INVALID_EXCEPTION;
     945  	// return Integer Indefinite
     946  	res = 0x8000000000000000ull;
     947  	BID_RETURN (res);
     948        }
     949        // else cases that can be rounded to a 64-bit int fall through
     950        // to '1 <= q + exp <= 20'
     951      } else if (q <= 19) {
     952        // C * 10^(21-q) >= 0xa0000000000000000
     953        __mul_64x64_to_128MACH (C, C1.w[0], ten2k64[21 - q]);
     954        if (C.w[1] >= 0x0a) {
     955  	// actually C.w[1] == 0x0a && C.w[0] >= 0x0000000000000000ull) {
     956  	// set invalid flag
     957  	*pfpsf |= INVALID_EXCEPTION;
     958  	// return Integer Indefinite
     959  	res = 0x8000000000000000ull;
     960  	BID_RETURN (res);
     961        }
     962        // else cases that can be rounded to a 64-bit int fall through
     963        // to '1 <= q + exp <= 20'
     964      } else if (q == 20) {
     965        // C >= 0x10000000000000000
     966        if (C1.w[1] >= 0x01) {
     967  	// actually C1.w[1] == 0x01 && C1.w[0] >= 0x0000000000000000ull) {
     968  	// set invalid flag
     969  	*pfpsf |= INVALID_EXCEPTION;
     970  	// return Integer Indefinite
     971  	res = 0x8000000000000000ull;
     972  	BID_RETURN (res);
     973        }
     974        // else cases that can be rounded to a 64-bit int fall through
     975        // to '1 <= q + exp <= 20'
     976      } else if (q == 21) {
     977        // C >= 0xa0000000000000000
     978        if (C1.w[1] >= 0x0a) {
     979  	// actually C1.w[1] == 0x0a && C1.w[0] >= 0x0000000000000000ull) {
     980  	// set invalid flag
     981  	*pfpsf |= INVALID_EXCEPTION;
     982  	// return Integer Indefinite
     983  	res = 0x8000000000000000ull;
     984  	BID_RETURN (res);
     985        }
     986        // else cases that can be rounded to a 64-bit int fall through
     987        // to '1 <= q + exp <= 20'
     988      } else {	// if 22 <= q <= 34 => 1 <= q - 21 <= 13
     989        // C  >= 10^(q-21) * 0xa0000000000000000 max 44 bits x 68 bits
     990        C.w[1] = 0x0a;
     991        C.w[0] = 0x0000000000000000ull;
     992        __mul_128x64_to_128 (C, ten2k64[q - 21], C);
     993        if (C1.w[1] > C.w[1] || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) {
     994  	// set invalid flag
     995  	*pfpsf |= INVALID_EXCEPTION;
     996  	// return Integer Indefinite
     997  	res = 0x8000000000000000ull;
     998  	BID_RETURN (res);
     999        }
    1000        // else cases that can be rounded to a 64-bit int fall through
    1001        // to '1 <= q + exp <= 20'
    1002      }
    1003    }
    1004    // n is not too large to be converted to int64 if 0 <= n < 2^64
    1005    // Note: some of the cases tested for above fall through to this point
    1006    if ((q + exp) <= 0) {	// n = +0.[0...0]c(0)c(1)...c(q-1)
    1007      // return 0
    1008      res = 0x0000000000000000ull;
    1009      BID_RETURN (res);
    1010    } else {	// if (1 <= q + exp <= 20, 1 <= q <= 34, -33 <= exp <= 19)
    1011      // 1 <= x < 2^64 so x can be rounded
    1012      // down to a 64-bit unsigned signed integer
    1013      if (exp < 0) {	// 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 20
    1014        ind = -exp;	// 1 <= ind <= 33; ind is a synonym for 'x'
    1015        // chop off ind digits from the lower part of C1
    1016        // C1 fits in 127 bits
    1017        // calculate C* and f*
    1018        // C* is actually floor(C*) in this case
    1019        // C* and f* need shifting and masking, as shown by
    1020        // shiftright128[] and maskhigh128[]
    1021        // 1 <= x <= 33
    1022        // kx = 10^(-x) = ten2mk128[ind - 1]
    1023        // C* = C1 * 10^(-x)
    1024        // the approximation of 10^(-x) was rounded up to 118 bits
    1025        __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
    1026        if (ind - 1 <= 21) {	// 0 <= ind - 1 <= 21
    1027  	Cstar.w[1] = P256.w[3];
    1028  	Cstar.w[0] = P256.w[2];
    1029        } else {	// 22 <= ind - 1 <= 33
    1030  	Cstar.w[1] = 0;
    1031  	Cstar.w[0] = P256.w[3];
    1032        }
    1033        // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
    1034        // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
    1035        // C* = floor(C*) (logical right shift; C has p decimal digits,
    1036        //     correct by Property 1)
    1037        // n = C* * 10^(e+x)
    1038  
    1039        // shift right C* by Ex-128 = shiftright128[ind]
    1040        shift = shiftright128[ind - 1];	// 0 <= shift <= 102
    1041        if (ind - 1 <= 21) {	// 0 <= ind - 1 <= 21
    1042  	Cstar.w[0] =
    1043  	  (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift));
    1044  	// redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
    1045        } else {	// 22 <= ind - 1 <= 33
    1046  	Cstar.w[0] = (Cstar.w[0] >> (shift - 64));	// 2 <= shift - 64 <= 38
    1047        }
    1048        res = Cstar.w[0];	// the result is positive
    1049      } else if (exp == 0) {
    1050        // 1 <= q <= 20, but x < 2^64 - 1/2 so in this case C1.w[1] has to be 0
    1051        // res = C (exact)
    1052        res = C1.w[0];
    1053      } else {
    1054        // if (exp > 0) => 1 <= exp <= 19, 1 <= q < 19, 2 <= q + exp <= 20
    1055        // res = C * 10^exp (exact) - must fit in 64 bits
    1056        res = C1.w[0] * ten2k64[exp];
    1057      }
    1058    }
    1059  }
    1060  
    1061  BID_RETURN (res);
    1062  }
    1063  
    1064  /*****************************************************************************
    1065   *  BID128_to_uint64_xfloor
    1066   ****************************************************************************/
    1067  
    1068  BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64,
    1069  					  bid128_to_uint64_xfloor, x)
    1070  
    1071       UINT64 res;
    1072       UINT64 x_sign;
    1073       UINT64 x_exp;
    1074       int exp;			// unbiased exponent
    1075    // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
    1076       BID_UI64DOUBLE tmp1;
    1077       unsigned int x_nr_bits;
    1078       int q, ind, shift;
    1079       UINT128 C1, C;
    1080       UINT128 Cstar;		// C* represents up to 34 decimal digits ~ 113 bits
    1081       UINT256 fstar;
    1082       UINT256 P256;
    1083  
    1084    // unpack x
    1085  x_sign = x.w[1] & MASK_SIGN;	// 0 for positive, MASK_SIGN for negative
    1086  x_exp = x.w[1] & MASK_EXP;	// biased and shifted left 49 bit positions
    1087  C1.w[1] = x.w[1] & MASK_COEFF;
    1088  C1.w[0] = x.w[0];
    1089  
    1090    // check for NaN or Infinity
    1091  if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
    1092      // x is special
    1093  if ((x.w[1] & MASK_NAN) == MASK_NAN) {	// x is NAN
    1094    if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {	// x is SNAN
    1095      // set invalid flag
    1096      *pfpsf |= INVALID_EXCEPTION;
    1097      // return Integer Indefinite
    1098      res = 0x8000000000000000ull;
    1099    } else {	// x is QNaN
    1100      // set invalid flag
    1101      *pfpsf |= INVALID_EXCEPTION;
    1102      // return Integer Indefinite
    1103      res = 0x8000000000000000ull;
    1104    }
    1105    BID_RETURN (res);
    1106  } else {	// x is not a NaN, so it must be infinity
    1107    if (!x_sign) {	// x is +inf
    1108      // set invalid flag
    1109      *pfpsf |= INVALID_EXCEPTION;
    1110      // return Integer Indefinite
    1111      res = 0x8000000000000000ull;
    1112    } else {	// x is -inf
    1113      // set invalid flag
    1114      *pfpsf |= INVALID_EXCEPTION;
    1115      // return Integer Indefinite
    1116      res = 0x8000000000000000ull;
    1117    }
    1118    BID_RETURN (res);
    1119  }
    1120  }
    1121    // check for non-canonical values (after the check for special values)
    1122  if ((C1.w[1] > 0x0001ed09bead87c0ull)
    1123      || (C1.w[1] == 0x0001ed09bead87c0ull
    1124  	&& (C1.w[0] > 0x378d8e63ffffffffull))
    1125      || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
    1126    res = 0x0000000000000000ull;
    1127    BID_RETURN (res);
    1128  } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
    1129    // x is 0
    1130    res = 0x0000000000000000ull;
    1131    BID_RETURN (res);
    1132  } else {	// x is not special and is not zero
    1133  
    1134    // if n < 0 then n cannot be converted to uint64 with RM
    1135    if (x_sign) {	// if n < 0 and q + exp = 20
    1136      // too large if c(0)c(1)...c(19).c(20)...c(q-1) > 0
    1137      // set invalid flag
    1138      *pfpsf |= INVALID_EXCEPTION;
    1139      // return Integer Indefinite
    1140      res = 0x8000000000000000ull;
    1141      BID_RETURN (res);
    1142    }
    1143    // q = nr. of decimal digits in x
    1144    //  determine first the nr. of bits in x
    1145    if (C1.w[1] == 0) {
    1146      if (C1.w[0] >= 0x0020000000000000ull) {	// x >= 2^53
    1147        // split the 64-bit value in two 32-bit halves to avoid rounding errors
    1148        if (C1.w[0] >= 0x0000000100000000ull) {	// x >= 2^32
    1149  	tmp1.d = (double) (C1.w[0] >> 32);	// exact conversion
    1150  	x_nr_bits =
    1151  	  33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1152        } else {	// x < 2^32
    1153  	tmp1.d = (double) (C1.w[0]);	// exact conversion
    1154  	x_nr_bits =
    1155  	  1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1156        }
    1157      } else {	// if x < 2^53
    1158        tmp1.d = (double) C1.w[0];	// exact conversion
    1159        x_nr_bits =
    1160  	1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1161      }
    1162    } else {	// C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
    1163      tmp1.d = (double) C1.w[1];	// exact conversion
    1164      x_nr_bits =
    1165        65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1166    }
    1167    q = nr_digits[x_nr_bits - 1].digits;
    1168    if (q == 0) {
    1169      q = nr_digits[x_nr_bits - 1].digits1;
    1170      if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
    1171  	|| (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi
    1172  	    && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
    1173        q++;
    1174    }
    1175    exp = (x_exp >> 49) - 6176;
    1176    if ((q + exp) > 20) {	// x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
    1177      // set invalid flag
    1178      *pfpsf |= INVALID_EXCEPTION;
    1179      // return Integer Indefinite
    1180      res = 0x8000000000000000ull;
    1181      BID_RETURN (res);
    1182    } else if ((q + exp) == 20) {	// x = c(0)c(1)...c(19).c(20)...c(q-1)
    1183      // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
    1184      // so x rounded to an integer may or may not fit in an unsigned 64-bit int
    1185      // the cases that do not fit are identified here; the ones that fit
    1186      // fall through and will be handled with other cases further,
    1187      // under '1 <= q + exp <= 20'
    1188      // if n > 0 and q + exp = 20
    1189      // if n >= 2^64 then n is too large
    1190      // <=> c(0)c(1)...c(19).c(20)...c(q-1) >= 2^64
    1191      // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 >= 2^64
    1192      // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 >= 5*2^65
    1193      // <=> C * 10^(21-q) >= 0xa0000000000000000, 1<=q<=34
    1194      if (q == 1) {
    1195        // C * 10^20 >= 0xa0000000000000000
    1196        __mul_128x64_to_128 (C, C1.w[0], ten2k128[0]);	// 10^20 * C
    1197        if (C.w[1] >= 0x0a) {
    1198  	// actually C.w[1] == 0x0a && C.w[0] >= 0x0000000000000000ull) {
    1199  	// set invalid flag
    1200  	*pfpsf |= INVALID_EXCEPTION;
    1201  	// return Integer Indefinite
    1202  	res = 0x8000000000000000ull;
    1203  	BID_RETURN (res);
    1204        }
    1205        // else cases that can be rounded to a 64-bit int fall through
    1206        // to '1 <= q + exp <= 20'
    1207      } else if (q <= 19) {
    1208        // C * 10^(21-q) >= 0xa0000000000000000
    1209        __mul_64x64_to_128MACH (C, C1.w[0], ten2k64[21 - q]);
    1210        if (C.w[1] >= 0x0a) {
    1211  	// actually C.w[1] == 0x0a && C.w[0] >= 0x0000000000000000ull) {
    1212  	// set invalid flag
    1213  	*pfpsf |= INVALID_EXCEPTION;
    1214  	// return Integer Indefinite
    1215  	res = 0x8000000000000000ull;
    1216  	BID_RETURN (res);
    1217        }
    1218        // else cases that can be rounded to a 64-bit int fall through
    1219        // to '1 <= q + exp <= 20'
    1220      } else if (q == 20) {
    1221        // C >= 0x10000000000000000
    1222        if (C1.w[1] >= 0x01) {
    1223  	// actually C1.w[1] == 0x01 && C1.w[0] >= 0x0000000000000000ull) {
    1224  	// set invalid flag
    1225  	*pfpsf |= INVALID_EXCEPTION;
    1226  	// return Integer Indefinite
    1227  	res = 0x8000000000000000ull;
    1228  	BID_RETURN (res);
    1229        }
    1230        // else cases that can be rounded to a 64-bit int fall through
    1231        // to '1 <= q + exp <= 20'
    1232      } else if (q == 21) {
    1233        // C >= 0xa0000000000000000
    1234        if (C1.w[1] >= 0x0a) {
    1235  	// actually C1.w[1] == 0x0a && C1.w[0] >= 0x0000000000000000ull) {
    1236  	// set invalid flag
    1237  	*pfpsf |= INVALID_EXCEPTION;
    1238  	// return Integer Indefinite
    1239  	res = 0x8000000000000000ull;
    1240  	BID_RETURN (res);
    1241        }
    1242        // else cases that can be rounded to a 64-bit int fall through
    1243        // to '1 <= q + exp <= 20'
    1244      } else {	// if 22 <= q <= 34 => 1 <= q - 21 <= 13
    1245        // C  >= 10^(q-21) * 0xa0000000000000000 max 44 bits x 68 bits
    1246        C.w[1] = 0x0a;
    1247        C.w[0] = 0x0000000000000000ull;
    1248        __mul_128x64_to_128 (C, ten2k64[q - 21], C);
    1249        if (C1.w[1] > C.w[1] || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) {
    1250  	// set invalid flag
    1251  	*pfpsf |= INVALID_EXCEPTION;
    1252  	// return Integer Indefinite
    1253  	res = 0x8000000000000000ull;
    1254  	BID_RETURN (res);
    1255        }
    1256        // else cases that can be rounded to a 64-bit int fall through
    1257        // to '1 <= q + exp <= 20'
    1258      }
    1259    }
    1260    // n is not too large to be converted to int64 if 0 <= n < 2^64
    1261    // Note: some of the cases tested for above fall through to this point
    1262    if ((q + exp) <= 0) {	// n = +0.[0...0]c(0)c(1)...c(q-1)
    1263      // set inexact flag
    1264      *pfpsf |= INEXACT_EXCEPTION;
    1265      // return 0
    1266      res = 0x0000000000000000ull;
    1267      BID_RETURN (res);
    1268    } else {	// if (1 <= q + exp <= 20, 1 <= q <= 34, -33 <= exp <= 19)
    1269      // 1 <= x < 2^64 so x can be rounded
    1270      // down to a 64-bit unsigned signed integer
    1271      if (exp < 0) {	// 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 20
    1272        ind = -exp;	// 1 <= ind <= 33; ind is a synonym for 'x'
    1273        // chop off ind digits from the lower part of C1
    1274        // C1 fits in 127 bits
    1275        // calculate C* and f*
    1276        // C* is actually floor(C*) in this case
    1277        // C* and f* need shifting and masking, as shown by
    1278        // shiftright128[] and maskhigh128[]
    1279        // 1 <= x <= 33
    1280        // kx = 10^(-x) = ten2mk128[ind - 1]
    1281        // C* = C1 * 10^(-x)
    1282        // the approximation of 10^(-x) was rounded up to 118 bits
    1283        __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
    1284        if (ind - 1 <= 21) {	// 0 <= ind - 1 <= 21
    1285  	Cstar.w[1] = P256.w[3];
    1286  	Cstar.w[0] = P256.w[2];
    1287  	fstar.w[3] = 0;
    1288  	fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
    1289  	fstar.w[1] = P256.w[1];
    1290  	fstar.w[0] = P256.w[0];
    1291        } else {	// 22 <= ind - 1 <= 33
    1292  	Cstar.w[1] = 0;
    1293  	Cstar.w[0] = P256.w[3];
    1294  	fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
    1295  	fstar.w[2] = P256.w[2];
    1296  	fstar.w[1] = P256.w[1];
    1297  	fstar.w[0] = P256.w[0];
    1298        }
    1299        // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
    1300        // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
    1301        // C* = floor(C*) (logical right shift; C has p decimal digits,
    1302        //     correct by Property 1)
    1303        // n = C* * 10^(e+x)
    1304  
    1305        // shift right C* by Ex-128 = shiftright128[ind]
    1306        shift = shiftright128[ind - 1];	// 0 <= shift <= 102
    1307        if (ind - 1 <= 21) {	// 0 <= ind - 1 <= 21
    1308  	Cstar.w[0] =
    1309  	  (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift));
    1310  	// redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
    1311        } else {	// 22 <= ind - 1 <= 33
    1312  	Cstar.w[0] = (Cstar.w[0] >> (shift - 64));	// 2 <= shift - 64 <= 38
    1313        }
    1314        // determine inexactness of the rounding of C*
    1315        // if (0 < f* < 10^(-x)) then
    1316        //   the result is exact
    1317        // else // if (f* > T*) then
    1318        //   the result is inexact
    1319        if (ind - 1 <= 2) {
    1320  	if (fstar.w[1] > ten2mk128trunc[ind - 1].w[1] ||
    1321  	    (fstar.w[1] == ten2mk128trunc[ind - 1].w[1] &&
    1322  	     fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
    1323  	  // set the inexact flag
    1324  	  *pfpsf |= INEXACT_EXCEPTION;
    1325  	}	// else the result is exact
    1326        } else if (ind - 1 <= 21) {	// if 3 <= ind <= 21
    1327  	if (fstar.w[2] || fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
    1328  	    || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
    1329  		&& fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
    1330  	  // set the inexact flag
    1331  	  *pfpsf |= INEXACT_EXCEPTION;
    1332  	}	// else the result is exact
    1333        } else {	// if 22 <= ind <= 33
    1334  	if (fstar.w[3] || fstar.w[2]
    1335  	    || fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
    1336  	    || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
    1337  		&& fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
    1338  	  // set the inexact flag
    1339  	  *pfpsf |= INEXACT_EXCEPTION;
    1340  	}	// else the result is exact
    1341        }
    1342  
    1343        res = Cstar.w[0];	// the result is positive
    1344      } else if (exp == 0) {
    1345        // 1 <= q <= 20, but x < 2^64 - 1/2 so in this case C1.w[1] has to be 0
    1346        // res = C (exact)
    1347        res = C1.w[0];
    1348      } else {
    1349        // if (exp > 0) => 1 <= exp <= 19, 1 <= q < 19, 2 <= q + exp <= 20
    1350        // res = C * 10^exp (exact) - must fit in 64 bits
    1351        res = C1.w[0] * ten2k64[exp];
    1352      }
    1353    }
    1354  }
    1355  
    1356  BID_RETURN (res);
    1357  }
    1358  
    1359  /*****************************************************************************
    1360   *  BID128_to_uint64_ceil
    1361   ****************************************************************************/
    1362  
    1363  BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64, bid128_to_uint64_ceil,
    1364  					  x)
    1365  
    1366       UINT64 res;
    1367       UINT64 x_sign;
    1368       UINT64 x_exp;
    1369       int exp;			// unbiased exponent
    1370    // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
    1371       BID_UI64DOUBLE tmp1;
    1372       unsigned int x_nr_bits;
    1373       int q, ind, shift;
    1374       UINT128 C1, C;
    1375       UINT128 Cstar;		// C* represents up to 34 decimal digits ~ 113 bits
    1376       UINT256 fstar;
    1377       UINT256 P256;
    1378  
    1379    // unpack x
    1380  x_sign = x.w[1] & MASK_SIGN;	// 0 for positive, MASK_SIGN for negative
    1381  x_exp = x.w[1] & MASK_EXP;	// biased and shifted left 49 bit positions
    1382  C1.w[1] = x.w[1] & MASK_COEFF;
    1383  C1.w[0] = x.w[0];
    1384  
    1385    // check for NaN or Infinity
    1386  if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
    1387      // x is special
    1388  if ((x.w[1] & MASK_NAN) == MASK_NAN) {	// x is NAN
    1389    if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {	// x is SNAN
    1390      // set invalid flag
    1391      *pfpsf |= INVALID_EXCEPTION;
    1392      // return Integer Indefinite
    1393      res = 0x8000000000000000ull;
    1394    } else {	// x is QNaN
    1395      // set invalid flag
    1396      *pfpsf |= INVALID_EXCEPTION;
    1397      // return Integer Indefinite
    1398      res = 0x8000000000000000ull;
    1399    }
    1400    BID_RETURN (res);
    1401  } else {	// x is not a NaN, so it must be infinity
    1402    if (!x_sign) {	// x is +inf
    1403      // set invalid flag
    1404      *pfpsf |= INVALID_EXCEPTION;
    1405      // return Integer Indefinite
    1406      res = 0x8000000000000000ull;
    1407    } else {	// x is -inf
    1408      // set invalid flag
    1409      *pfpsf |= INVALID_EXCEPTION;
    1410      // return Integer Indefinite
    1411      res = 0x8000000000000000ull;
    1412    }
    1413    BID_RETURN (res);
    1414  }
    1415  }
    1416    // check for non-canonical values (after the check for special values)
    1417  if ((C1.w[1] > 0x0001ed09bead87c0ull)
    1418      || (C1.w[1] == 0x0001ed09bead87c0ull
    1419  	&& (C1.w[0] > 0x378d8e63ffffffffull))
    1420      || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
    1421    res = 0x0000000000000000ull;
    1422    BID_RETURN (res);
    1423  } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
    1424    // x is 0
    1425    res = 0x0000000000000000ull;
    1426    BID_RETURN (res);
    1427  } else {	// x is not special and is not zero
    1428  
    1429    // q = nr. of decimal digits in x
    1430    //  determine first the nr. of bits in x
    1431    if (C1.w[1] == 0) {
    1432      if (C1.w[0] >= 0x0020000000000000ull) {	// x >= 2^53
    1433        // split the 64-bit value in two 32-bit halves to avoid rounding errors
    1434        if (C1.w[0] >= 0x0000000100000000ull) {	// x >= 2^32
    1435  	tmp1.d = (double) (C1.w[0] >> 32);	// exact conversion
    1436  	x_nr_bits =
    1437  	  33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1438        } else {	// x < 2^32
    1439  	tmp1.d = (double) (C1.w[0]);	// exact conversion
    1440  	x_nr_bits =
    1441  	  1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1442        }
    1443      } else {	// if x < 2^53
    1444        tmp1.d = (double) C1.w[0];	// exact conversion
    1445        x_nr_bits =
    1446  	1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1447      }
    1448    } else {	// C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
    1449      tmp1.d = (double) C1.w[1];	// exact conversion
    1450      x_nr_bits =
    1451        65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1452    }
    1453    q = nr_digits[x_nr_bits - 1].digits;
    1454    if (q == 0) {
    1455      q = nr_digits[x_nr_bits - 1].digits1;
    1456      if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
    1457  	|| (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi
    1458  	    && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
    1459        q++;
    1460    }
    1461    exp = (x_exp >> 49) - 6176;
    1462    if ((q + exp) > 20) {	// x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
    1463      // set invalid flag
    1464      *pfpsf |= INVALID_EXCEPTION;
    1465      // return Integer Indefinite
    1466      res = 0x8000000000000000ull;
    1467      BID_RETURN (res);
    1468    } else if ((q + exp) == 20) {	// x = c(0)c(1)...c(19).c(20)...c(q-1)
    1469      // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
    1470      // so x rounded to an integer may or may not fit in an unsigned 64-bit int
    1471      // the cases that do not fit are identified here; the ones that fit
    1472      // fall through and will be handled with other cases further,
    1473      // under '1 <= q + exp <= 20'
    1474      if (x_sign) {	// if n < 0 and q + exp = 20
    1475        // if n <= -1 then n cannot be converted to uint64 with RZ
    1476        // too large if c(0)c(1)...c(19).c(20)...c(q-1) >= 1
    1477        // <=> 0.c(0)c(1)...c(q-1) * 10^21 >= 0x0a, 1<=q<=34
    1478        // <=> C * 10^(21-q) >= 0x0a, 1<=q<=34
    1479        if (q == 21) {
    1480  	// C >= a 
    1481  	if (C1.w[1] != 0 || C1.w[0] >= 0x0aull) {
    1482  	  // set invalid flag
    1483  	  *pfpsf |= INVALID_EXCEPTION;
    1484  	  // return Integer Indefinite
    1485  	  res = 0x8000000000000000ull;
    1486  	  BID_RETURN (res);
    1487  	}
    1488  	// else cases that can be rounded to 64-bit unsigned int fall through
    1489  	// to '1 <= q + exp <= 20'
    1490        } else {
    1491  	// if 1 <= q <= 20
    1492  	//   C * 10^(21-q) >= a is true because C >= 1 and 10^(21-q) >= 10
    1493  	// if 22 <= q <= 34 => 1 <= q - 21 <= 13
    1494  	//  C >= a * 10^(q-21) is true because C > 2^64 and a*10^(q-21) < 2^64
    1495  	// set invalid flag
    1496  	*pfpsf |= INVALID_EXCEPTION;
    1497  	// return Integer Indefinite
    1498  	res = 0x8000000000000000ull;
    1499  	BID_RETURN (res);
    1500        }
    1501      } else {	// if n > 0 and q + exp = 20
    1502        // if n > 2^64 - 1 then n is too large
    1503        // <=> c(0)c(1)...c(19).c(20)...c(q-1) > 2^64 - 1
    1504        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 > 2^64 - 1
    1505        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 > 10 * (2^64 - 1) 
    1506        // <=> C * 10^(21-q) > 0x9fffffffffffffff6, 1<=q<=34
    1507        if (q == 1) {
    1508  	// C * 10^20 > 0x9fffffffffffffff6
    1509  	__mul_128x64_to_128 (C, C1.w[0], ten2k128[0]);	// 10^20 * C
    1510  	if (C.w[1] > 0x09 || (C.w[1] == 0x09
    1511  			      && C.w[0] > 0xfffffffffffffff6ull)) {
    1512  	  // set invalid flag
    1513  	  *pfpsf |= INVALID_EXCEPTION;
    1514  	  // return Integer Indefinite
    1515  	  res = 0x8000000000000000ull;
    1516  	  BID_RETURN (res);
    1517  	}
    1518  	// else cases that can be rounded to a 64-bit int fall through
    1519  	// to '1 <= q + exp <= 20'
    1520        } else if (q <= 19) {
    1521  	// C * 10^(21-q) > 0x9fffffffffffffff6
    1522  	__mul_64x64_to_128MACH (C, C1.w[0], ten2k64[21 - q]);
    1523  	if (C.w[1] > 0x09 || (C.w[1] == 0x09
    1524  			      && C.w[0] > 0xfffffffffffffff6ull)) {
    1525  	  // set invalid flag
    1526  	  *pfpsf |= INVALID_EXCEPTION;
    1527  	  // return Integer Indefinite
    1528  	  res = 0x8000000000000000ull;
    1529  	  BID_RETURN (res);
    1530  	}
    1531  	// else cases that can be rounded to a 64-bit int fall through
    1532  	// to '1 <= q + exp <= 20'
    1533        } else if (q == 20) {
    1534  	// C > 0xffffffffffffffff
    1535  	if (C1.w[1]) {
    1536  	  // set invalid flag
    1537  	  *pfpsf |= INVALID_EXCEPTION;
    1538  	  // return Integer Indefinite
    1539  	  res = 0x8000000000000000ull;
    1540  	  BID_RETURN (res);
    1541  	}
    1542  	// else cases that can be rounded to a 64-bit int fall through
    1543  	// to '1 <= q + exp <= 20'
    1544        } else if (q == 21) {
    1545  	// C > 0x9fffffffffffffff6
    1546  	if (C1.w[1] > 0x09 || (C1.w[1] == 0x09
    1547  			       && C1.w[0] > 0xfffffffffffffff6ull)) {
    1548  	  // set invalid flag
    1549  	  *pfpsf |= INVALID_EXCEPTION;
    1550  	  // return Integer Indefinite
    1551  	  res = 0x8000000000000000ull;
    1552  	  BID_RETURN (res);
    1553  	}
    1554  	// else cases that can be rounded to a 64-bit int fall through
    1555  	// to '1 <= q + exp <= 20'
    1556        } else {	// if 22 <= q <= 34 => 1 <= q - 21 <= 13
    1557  	// C  > 10^(q-21) * 0x9fffffffffffffff6 max 44 bits x 68 bits
    1558  	C.w[1] = 0x09;
    1559  	C.w[0] = 0xfffffffffffffff6ull;
    1560  	__mul_128x64_to_128 (C, ten2k64[q - 21], C);
    1561  	if (C1.w[1] > C.w[1] || (C1.w[1] == C.w[1] && C1.w[0] > C.w[0])) {
    1562  	  // set invalid flag
    1563  	  *pfpsf |= INVALID_EXCEPTION;
    1564  	  // return Integer Indefinite
    1565  	  res = 0x8000000000000000ull;
    1566  	  BID_RETURN (res);
    1567  	}
    1568  	// else cases that can be rounded to a 64-bit int fall through
    1569  	// to '1 <= q + exp <= 20'
    1570        }
    1571      }
    1572    }
    1573    // n is not too large to be converted to int64 if -1 < n <= 2^64 - 1
    1574    // Note: some of the cases tested for above fall through to this point
    1575    if ((q + exp) <= 0) {	// n = +/-0.[0...0]c(0)c(1)...c(q-1)
    1576      // return 0 or 1
    1577      if (x_sign)
    1578        res = 0x0000000000000000ull;
    1579      else
    1580        res = 0x0000000000000001ull;
    1581      BID_RETURN (res);
    1582    } else {	// if (1 <= q + exp <= 20, 1 <= q <= 34, -33 <= exp <= 19)
    1583      // x <= -1 or 1 <= x < 2^64 so if positive x can be rounded
    1584      // to zero to a 64-bit unsigned signed integer
    1585      if (x_sign) {	// x <= -1
    1586        // set invalid flag
    1587        *pfpsf |= INVALID_EXCEPTION;
    1588        // return Integer Indefinite
    1589        res = 0x8000000000000000ull;
    1590        BID_RETURN (res);
    1591      }
    1592      // 1 <= x <= 2^64 - 1 so x can be rounded
    1593      // to zero to a 64-bit unsigned integer
    1594      if (exp < 0) {	// 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 20
    1595        ind = -exp;	// 1 <= ind <= 33; ind is a synonym for 'x'
    1596        // chop off ind digits from the lower part of C1
    1597        // C1 fits in 127 bits
    1598        // calculate C* and f*
    1599        // C* is actually floor(C*) in this case
    1600        // C* and f* need shifting and masking, as shown by
    1601        // shiftright128[] and maskhigh128[]
    1602        // 1 <= x <= 33
    1603        // kx = 10^(-x) = ten2mk128[ind - 1]
    1604        // C* = C1 * 10^(-x)
    1605        // the approximation of 10^(-x) was rounded up to 118 bits
    1606        __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
    1607        if (ind - 1 <= 21) {	// 0 <= ind - 1 <= 21
    1608  	Cstar.w[1] = P256.w[3];
    1609  	Cstar.w[0] = P256.w[2];
    1610  	fstar.w[3] = 0;
    1611  	fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
    1612  	fstar.w[1] = P256.w[1];
    1613  	fstar.w[0] = P256.w[0];
    1614        } else {	// 22 <= ind - 1 <= 33
    1615  	Cstar.w[1] = 0;
    1616  	Cstar.w[0] = P256.w[3];
    1617  	fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
    1618  	fstar.w[2] = P256.w[2];
    1619  	fstar.w[1] = P256.w[1];
    1620  	fstar.w[0] = P256.w[0];
    1621        }
    1622        // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
    1623        // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
    1624        // C* = floor(C*) (logical right shift; C has p decimal digits,
    1625        //     correct by Property 1)
    1626        // n = C* * 10^(e+x)
    1627  
    1628        // shift right C* by Ex-128 = shiftright128[ind]
    1629        shift = shiftright128[ind - 1];	// 0 <= shift <= 102
    1630        if (ind - 1 <= 21) {	// 0 <= ind - 1 <= 21
    1631  	Cstar.w[0] =
    1632  	  (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift));
    1633  	// redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
    1634        } else {	// 22 <= ind - 1 <= 33
    1635  	Cstar.w[0] = (Cstar.w[0] >> (shift - 64));	// 2 <= shift - 64 <= 38
    1636        }
    1637        // if the result is positive and inexact, need to add 1 to it
    1638  
    1639        // determine inexactness of the rounding of C*
    1640        // if (0 < f* < 10^(-x)) then
    1641        //   the result is exact
    1642        // else // if (f* > T*) then
    1643        //   the result is inexact
    1644        if (ind - 1 <= 2) {
    1645  	if (fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
    1646  	    || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
    1647  		&& fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
    1648  	  if (!x_sign) {	// positive and inexact
    1649  	    Cstar.w[0]++;
    1650  	    if (Cstar.w[0] == 0x0)
    1651  	      Cstar.w[1]++;
    1652  	  }
    1653  	}	// else the result is exact
    1654        } else if (ind - 1 <= 21) {	// if 3 <= ind <= 21
    1655  	if (fstar.w[2] || fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
    1656  	    || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
    1657  		&& fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
    1658  	  if (!x_sign) {	// positive and inexact
    1659  	    Cstar.w[0]++;
    1660  	    if (Cstar.w[0] == 0x0)
    1661  	      Cstar.w[1]++;
    1662  	  }
    1663  	}	// else the result is exact
    1664        } else {	// if 22 <= ind <= 33
    1665  	if (fstar.w[3] || fstar.w[2]
    1666  	    || fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
    1667  	    || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
    1668  		&& fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
    1669  	  if (!x_sign) {	// positive and inexact
    1670  	    Cstar.w[0]++;
    1671  	    if (Cstar.w[0] == 0x0)
    1672  	      Cstar.w[1]++;
    1673  	  }
    1674  	}	// else the result is exact
    1675        }
    1676  
    1677        res = Cstar.w[0];	// the result is positive
    1678      } else if (exp == 0) {
    1679        // 1 <= q <= 20, but x < 2^64 - 1/2 so in this case C1.w[1] has to be 0
    1680        // res = C (exact)
    1681        res = C1.w[0];
    1682      } else {
    1683        // if (exp > 0) => 1 <= exp <= 19, 1 <= q < 19, 2 <= q + exp <= 20
    1684        // res = C * 10^exp (exact) - must fit in 64 bits
    1685        res = C1.w[0] * ten2k64[exp];
    1686      }
    1687    }
    1688  }
    1689  
    1690  BID_RETURN (res);
    1691  }
    1692  
    1693  /*****************************************************************************
    1694   *  BID128_to_uint64_xceil
    1695   ****************************************************************************/
    1696  
    1697  BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64,
    1698  					  bid128_to_uint64_xceil, x)
    1699  
    1700       UINT64 res;
    1701       UINT64 x_sign;
    1702       UINT64 x_exp;
    1703       int exp;			// unbiased exponent
    1704    // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
    1705       BID_UI64DOUBLE tmp1;
    1706       unsigned int x_nr_bits;
    1707       int q, ind, shift;
    1708       UINT128 C1, C;
    1709       UINT128 Cstar;		// C* represents up to 34 decimal digits ~ 113 bits
    1710       UINT256 fstar;
    1711       UINT256 P256;
    1712  
    1713    // unpack x
    1714  x_sign = x.w[1] & MASK_SIGN;	// 0 for positive, MASK_SIGN for negative
    1715  x_exp = x.w[1] & MASK_EXP;	// biased and shifted left 49 bit positions
    1716  C1.w[1] = x.w[1] & MASK_COEFF;
    1717  C1.w[0] = x.w[0];
    1718  
    1719    // check for NaN or Infinity
    1720  if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
    1721      // x is special
    1722  if ((x.w[1] & MASK_NAN) == MASK_NAN) {	// x is NAN
    1723    if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {	// x is SNAN
    1724      // set invalid flag
    1725      *pfpsf |= INVALID_EXCEPTION;
    1726      // return Integer Indefinite
    1727      res = 0x8000000000000000ull;
    1728    } else {	// x is QNaN
    1729      // set invalid flag
    1730      *pfpsf |= INVALID_EXCEPTION;
    1731      // return Integer Indefinite
    1732      res = 0x8000000000000000ull;
    1733    }
    1734    BID_RETURN (res);
    1735  } else {	// x is not a NaN, so it must be infinity
    1736    if (!x_sign) {	// x is +inf
    1737      // set invalid flag
    1738      *pfpsf |= INVALID_EXCEPTION;
    1739      // return Integer Indefinite
    1740      res = 0x8000000000000000ull;
    1741    } else {	// x is -inf
    1742      // set invalid flag
    1743      *pfpsf |= INVALID_EXCEPTION;
    1744      // return Integer Indefinite
    1745      res = 0x8000000000000000ull;
    1746    }
    1747    BID_RETURN (res);
    1748  }
    1749  }
    1750    // check for non-canonical values (after the check for special values)
    1751  if ((C1.w[1] > 0x0001ed09bead87c0ull)
    1752      || (C1.w[1] == 0x0001ed09bead87c0ull
    1753  	&& (C1.w[0] > 0x378d8e63ffffffffull))
    1754      || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
    1755    res = 0x0000000000000000ull;
    1756    BID_RETURN (res);
    1757  } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
    1758    // x is 0
    1759    res = 0x0000000000000000ull;
    1760    BID_RETURN (res);
    1761  } else {	// x is not special and is not zero
    1762  
    1763    // q = nr. of decimal digits in x
    1764    //  determine first the nr. of bits in x
    1765    if (C1.w[1] == 0) {
    1766      if (C1.w[0] >= 0x0020000000000000ull) {	// x >= 2^53
    1767        // split the 64-bit value in two 32-bit halves to avoid rounding errors
    1768        if (C1.w[0] >= 0x0000000100000000ull) {	// x >= 2^32
    1769  	tmp1.d = (double) (C1.w[0] >> 32);	// exact conversion
    1770  	x_nr_bits =
    1771  	  33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1772        } else {	// x < 2^32
    1773  	tmp1.d = (double) (C1.w[0]);	// exact conversion
    1774  	x_nr_bits =
    1775  	  1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1776        }
    1777      } else {	// if x < 2^53
    1778        tmp1.d = (double) C1.w[0];	// exact conversion
    1779        x_nr_bits =
    1780  	1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1781      }
    1782    } else {	// C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
    1783      tmp1.d = (double) C1.w[1];	// exact conversion
    1784      x_nr_bits =
    1785        65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1786    }
    1787    q = nr_digits[x_nr_bits - 1].digits;
    1788    if (q == 0) {
    1789      q = nr_digits[x_nr_bits - 1].digits1;
    1790      if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
    1791  	|| (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi
    1792  	    && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
    1793        q++;
    1794    }
    1795    exp = (x_exp >> 49) - 6176;
    1796    if ((q + exp) > 20) {	// x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
    1797      // set invalid flag
    1798      *pfpsf |= INVALID_EXCEPTION;
    1799      // return Integer Indefinite
    1800      res = 0x8000000000000000ull;
    1801      BID_RETURN (res);
    1802    } else if ((q + exp) == 20) {	// x = c(0)c(1)...c(19).c(20)...c(q-1)
    1803      // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
    1804      // so x rounded to an integer may or may not fit in an unsigned 64-bit int
    1805      // the cases that do not fit are identified here; the ones that fit
    1806      // fall through and will be handled with other cases further,
    1807      // under '1 <= q + exp <= 20'
    1808      if (x_sign) {	// if n < 0 and q + exp = 20
    1809        // if n <= -1 then n cannot be converted to uint64 with RZ
    1810        // too large if c(0)c(1)...c(19).c(20)...c(q-1) >= 1
    1811        // <=> 0.c(0)c(1)...c(q-1) * 10^21 >= 0x0a, 1<=q<=34
    1812        // <=> C * 10^(21-q) >= 0x0a, 1<=q<=34
    1813        if (q == 21) {
    1814  	// C >= a 
    1815  	if (C1.w[1] != 0 || C1.w[0] >= 0x0aull) {
    1816  	  // set invalid flag
    1817  	  *pfpsf |= INVALID_EXCEPTION;
    1818  	  // return Integer Indefinite
    1819  	  res = 0x8000000000000000ull;
    1820  	  BID_RETURN (res);
    1821  	}
    1822  	// else cases that can be rounded to 64-bit unsigned int fall through
    1823  	// to '1 <= q + exp <= 20'
    1824        } else {
    1825  	// if 1 <= q <= 20
    1826  	//   C * 10^(21-q) >= a is true because C >= 1 and 10^(21-q) >= 10
    1827  	// if 22 <= q <= 34 => 1 <= q - 21 <= 13
    1828  	//  C >= a * 10^(q-21) is true because C > 2^64 and a*10^(q-21) < 2^64
    1829  	// set invalid flag
    1830  	*pfpsf |= INVALID_EXCEPTION;
    1831  	// return Integer Indefinite
    1832  	res = 0x8000000000000000ull;
    1833  	BID_RETURN (res);
    1834        }
    1835      } else {	// if n > 0 and q + exp = 20
    1836        // if n > 2^64 - 1 then n is too large
    1837        // <=> c(0)c(1)...c(19).c(20)...c(q-1) > 2^64 - 1
    1838        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 > 2^64 - 1
    1839        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 > 10 * (2^64 - 1) 
    1840        // <=> C * 10^(21-q) > 0x9fffffffffffffff6, 1<=q<=34
    1841        if (q == 1) {
    1842  	// C * 10^20 > 0x9fffffffffffffff6
    1843  	__mul_128x64_to_128 (C, C1.w[0], ten2k128[0]);	// 10^20 * C
    1844  	if (C.w[1] > 0x09 || (C.w[1] == 0x09
    1845  			      && C.w[0] > 0xfffffffffffffff6ull)) {
    1846  	  // set invalid flag
    1847  	  *pfpsf |= INVALID_EXCEPTION;
    1848  	  // return Integer Indefinite
    1849  	  res = 0x8000000000000000ull;
    1850  	  BID_RETURN (res);
    1851  	}
    1852  	// else cases that can be rounded to a 64-bit int fall through
    1853  	// to '1 <= q + exp <= 20'
    1854        } else if (q <= 19) {
    1855  	// C * 10^(21-q) > 0x9fffffffffffffff6
    1856  	__mul_64x64_to_128MACH (C, C1.w[0], ten2k64[21 - q]);
    1857  	if (C.w[1] > 0x09 || (C.w[1] == 0x09
    1858  			      && C.w[0] > 0xfffffffffffffff6ull)) {
    1859  	  // set invalid flag
    1860  	  *pfpsf |= INVALID_EXCEPTION;
    1861  	  // return Integer Indefinite
    1862  	  res = 0x8000000000000000ull;
    1863  	  BID_RETURN (res);
    1864  	}
    1865  	// else cases that can be rounded to a 64-bit int fall through
    1866  	// to '1 <= q + exp <= 20'
    1867        } else if (q == 20) {
    1868  	// C > 0xffffffffffffffff
    1869  	if (C1.w[1]) {
    1870  	  // set invalid flag
    1871  	  *pfpsf |= INVALID_EXCEPTION;
    1872  	  // return Integer Indefinite
    1873  	  res = 0x8000000000000000ull;
    1874  	  BID_RETURN (res);
    1875  	}
    1876  	// else cases that can be rounded to a 64-bit int fall through
    1877  	// to '1 <= q + exp <= 20'
    1878        } else if (q == 21) {
    1879  	// C > 0x9fffffffffffffff6
    1880  	if (C1.w[1] > 0x09 || (C1.w[1] == 0x09
    1881  			       && C1.w[0] > 0xfffffffffffffff6ull)) {
    1882  	  // set invalid flag
    1883  	  *pfpsf |= INVALID_EXCEPTION;
    1884  	  // return Integer Indefinite
    1885  	  res = 0x8000000000000000ull;
    1886  	  BID_RETURN (res);
    1887  	}
    1888  	// else cases that can be rounded to a 64-bit int fall through
    1889  	// to '1 <= q + exp <= 20'
    1890        } else {	// if 22 <= q <= 34 => 1 <= q - 21 <= 13
    1891  	// C  > 10^(q-21) * 0x9fffffffffffffff6 max 44 bits x 68 bits
    1892  	C.w[1] = 0x09;
    1893  	C.w[0] = 0xfffffffffffffff6ull;
    1894  	__mul_128x64_to_128 (C, ten2k64[q - 21], C);
    1895  	if (C1.w[1] > C.w[1] || (C1.w[1] == C.w[1] && C1.w[0] > C.w[0])) {
    1896  	  // set invalid flag
    1897  	  *pfpsf |= INVALID_EXCEPTION;
    1898  	  // return Integer Indefinite
    1899  	  res = 0x8000000000000000ull;
    1900  	  BID_RETURN (res);
    1901  	}
    1902  	// else cases that can be rounded to a 64-bit int fall through
    1903  	// to '1 <= q + exp <= 20'
    1904        }
    1905      }
    1906    }
    1907    // n is not too large to be converted to int64 if -1 < n <= 2^64 - 1
    1908    // Note: some of the cases tested for above fall through to this point
    1909    if ((q + exp) <= 0) {	// n = +/-0.[0...0]c(0)c(1)...c(q-1)
    1910      // set inexact flag
    1911      *pfpsf |= INEXACT_EXCEPTION;
    1912      // return 0 or 1
    1913      if (x_sign)
    1914        res = 0x0000000000000000ull;
    1915      else
    1916        res = 0x0000000000000001ull;
    1917      BID_RETURN (res);
    1918    } else {	// if (1 <= q + exp <= 20, 1 <= q <= 34, -33 <= exp <= 19)
    1919      // x <= -1 or 1 <= x < 2^64 so if positive x can be rounded
    1920      // to zero to a 64-bit unsigned signed integer
    1921      if (x_sign) {	// x <= -1
    1922        // set invalid flag
    1923        *pfpsf |= INVALID_EXCEPTION;
    1924        // return Integer Indefinite
    1925        res = 0x8000000000000000ull;
    1926        BID_RETURN (res);
    1927      }
    1928      // 1 <= x <= 2^64 - 1 so x can be rounded
    1929      // to zero to a 64-bit unsigned integer
    1930      if (exp < 0) {	// 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 20
    1931        ind = -exp;	// 1 <= ind <= 33; ind is a synonym for 'x'
    1932        // chop off ind digits from the lower part of C1
    1933        // C1 fits in 127 bits
    1934        // calculate C* and f*
    1935        // C* is actually floor(C*) in this case
    1936        // C* and f* need shifting and masking, as shown by
    1937        // shiftright128[] and maskhigh128[]
    1938        // 1 <= x <= 33
    1939        // kx = 10^(-x) = ten2mk128[ind - 1]
    1940        // C* = C1 * 10^(-x)
    1941        // the approximation of 10^(-x) was rounded up to 118 bits
    1942        __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
    1943        if (ind - 1 <= 21) {	// 0 <= ind - 1 <= 21
    1944  	Cstar.w[1] = P256.w[3];
    1945  	Cstar.w[0] = P256.w[2];
    1946  	fstar.w[3] = 0;
    1947  	fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
    1948  	fstar.w[1] = P256.w[1];
    1949  	fstar.w[0] = P256.w[0];
    1950        } else {	// 22 <= ind - 1 <= 33
    1951  	Cstar.w[1] = 0;
    1952  	Cstar.w[0] = P256.w[3];
    1953  	fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
    1954  	fstar.w[2] = P256.w[2];
    1955  	fstar.w[1] = P256.w[1];
    1956  	fstar.w[0] = P256.w[0];
    1957        }
    1958        // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
    1959        // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
    1960        // C* = floor(C*) (logical right shift; C has p decimal digits,
    1961        //     correct by Property 1)
    1962        // n = C* * 10^(e+x)
    1963  
    1964        // shift right C* by Ex-128 = shiftright128[ind]
    1965        shift = shiftright128[ind - 1];	// 0 <= shift <= 102
    1966        if (ind - 1 <= 21) {	// 0 <= ind - 1 <= 21
    1967  	Cstar.w[0] =
    1968  	  (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift));
    1969  	// redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
    1970        } else {	// 22 <= ind - 1 <= 33
    1971  	Cstar.w[0] = (Cstar.w[0] >> (shift - 64));	// 2 <= shift - 64 <= 38
    1972        }
    1973        // if the result is positive and inexact, need to add 1 to it
    1974  
    1975        // determine inexactness of the rounding of C*
    1976        // if (0 < f* < 10^(-x)) then
    1977        //   the result is exact
    1978        // else // if (f* > T*) then
    1979        //   the result is inexact
    1980        if (ind - 1 <= 2) {
    1981  	if (fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
    1982  	    || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
    1983  		&& fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
    1984  	  if (!x_sign) {	// positive and inexact
    1985  	    Cstar.w[0]++;
    1986  	    if (Cstar.w[0] == 0x0)
    1987  	      Cstar.w[1]++;
    1988  	  }
    1989  	  // set the inexact flag
    1990  	  *pfpsf |= INEXACT_EXCEPTION;
    1991  	}	// else the result is exact
    1992        } else if (ind - 1 <= 21) {	// if 3 <= ind <= 21
    1993  	if (fstar.w[2] || fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
    1994  	    || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
    1995  		&& fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
    1996  	  if (!x_sign) {	// positive and inexact
    1997  	    Cstar.w[0]++;
    1998  	    if (Cstar.w[0] == 0x0)
    1999  	      Cstar.w[1]++;
    2000  	  }
    2001  	  // set the inexact flag
    2002  	  *pfpsf |= INEXACT_EXCEPTION;
    2003  	}	// else the result is exact
    2004        } else {	// if 22 <= ind <= 33
    2005  	if (fstar.w[3] || fstar.w[2]
    2006  	    || fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
    2007  	    || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
    2008  		&& fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
    2009  	  if (!x_sign) {	// positive and inexact
    2010  	    Cstar.w[0]++;
    2011  	    if (Cstar.w[0] == 0x0)
    2012  	      Cstar.w[1]++;
    2013  	  }
    2014  	  // set the inexact flag
    2015  	  *pfpsf |= INEXACT_EXCEPTION;
    2016  	}	// else the result is exact
    2017        }
    2018  
    2019        res = Cstar.w[0];	// the result is positive
    2020      } else if (exp == 0) {
    2021        // 1 <= q <= 20, but x < 2^64 - 1/2 so in this case C1.w[1] has to be 0
    2022        // res = C (exact)
    2023        res = C1.w[0];
    2024      } else {
    2025        // if (exp > 0) => 1 <= exp <= 19, 1 <= q < 19, 2 <= q + exp <= 20
    2026        // res = C * 10^exp (exact) - must fit in 64 bits
    2027        res = C1.w[0] * ten2k64[exp];
    2028      }
    2029    }
    2030  }
    2031  
    2032  BID_RETURN (res);
    2033  }
    2034  
    2035  /*****************************************************************************
    2036   *  BID128_to_uint64_int
    2037   ****************************************************************************/
    2038  
    2039  BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64, bid128_to_uint64_int,
    2040  					  x)
    2041  
    2042       UINT64 res;
    2043       UINT64 x_sign;
    2044       UINT64 x_exp;
    2045       int exp;			// unbiased exponent
    2046    // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
    2047       BID_UI64DOUBLE tmp1;
    2048       unsigned int x_nr_bits;
    2049       int q, ind, shift;
    2050       UINT128 C1, C;
    2051       UINT128 Cstar;		// C* represents up to 34 decimal digits ~ 113 bits
    2052       UINT256 P256;
    2053  
    2054    // unpack x
    2055  x_sign = x.w[1] & MASK_SIGN;	// 0 for positive, MASK_SIGN for negative
    2056  x_exp = x.w[1] & MASK_EXP;	// biased and shifted left 49 bit positions
    2057  C1.w[1] = x.w[1] & MASK_COEFF;
    2058  C1.w[0] = x.w[0];
    2059  
    2060    // check for NaN or Infinity
    2061  if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
    2062      // x is special
    2063  if ((x.w[1] & MASK_NAN) == MASK_NAN) {	// x is NAN
    2064    if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {	// x is SNAN
    2065      // set invalid flag
    2066      *pfpsf |= INVALID_EXCEPTION;
    2067      // return Integer Indefinite
    2068      res = 0x8000000000000000ull;
    2069    } else {	// x is QNaN
    2070      // set invalid flag
    2071      *pfpsf |= INVALID_EXCEPTION;
    2072      // return Integer Indefinite
    2073      res = 0x8000000000000000ull;
    2074    }
    2075    BID_RETURN (res);
    2076  } else {	// x is not a NaN, so it must be infinity
    2077    if (!x_sign) {	// x is +inf
    2078      // set invalid flag
    2079      *pfpsf |= INVALID_EXCEPTION;
    2080      // return Integer Indefinite
    2081      res = 0x8000000000000000ull;
    2082    } else {	// x is -inf
    2083      // set invalid flag
    2084      *pfpsf |= INVALID_EXCEPTION;
    2085      // return Integer Indefinite
    2086      res = 0x8000000000000000ull;
    2087    }
    2088    BID_RETURN (res);
    2089  }
    2090  }
    2091    // check for non-canonical values (after the check for special values)
    2092  if ((C1.w[1] > 0x0001ed09bead87c0ull)
    2093      || (C1.w[1] == 0x0001ed09bead87c0ull
    2094  	&& (C1.w[0] > 0x378d8e63ffffffffull))
    2095      || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
    2096    res = 0x0000000000000000ull;
    2097    BID_RETURN (res);
    2098  } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
    2099    // x is 0
    2100    res = 0x0000000000000000ull;
    2101    BID_RETURN (res);
    2102  } else {	// x is not special and is not zero
    2103  
    2104    // q = nr. of decimal digits in x
    2105    //  determine first the nr. of bits in x
    2106    if (C1.w[1] == 0) {
    2107      if (C1.w[0] >= 0x0020000000000000ull) {	// x >= 2^53
    2108        // split the 64-bit value in two 32-bit halves to avoid rounding errors
    2109        if (C1.w[0] >= 0x0000000100000000ull) {	// x >= 2^32
    2110  	tmp1.d = (double) (C1.w[0] >> 32);	// exact conversion
    2111  	x_nr_bits =
    2112  	  33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    2113        } else {	// x < 2^32
    2114  	tmp1.d = (double) (C1.w[0]);	// exact conversion
    2115  	x_nr_bits =
    2116  	  1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    2117        }
    2118      } else {	// if x < 2^53
    2119        tmp1.d = (double) C1.w[0];	// exact conversion
    2120        x_nr_bits =
    2121  	1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    2122      }
    2123    } else {	// C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
    2124      tmp1.d = (double) C1.w[1];	// exact conversion
    2125      x_nr_bits =
    2126        65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    2127    }
    2128    q = nr_digits[x_nr_bits - 1].digits;
    2129    if (q == 0) {
    2130      q = nr_digits[x_nr_bits - 1].digits1;
    2131      if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
    2132  	|| (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi
    2133  	    && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
    2134        q++;
    2135    }
    2136    exp = (x_exp >> 49) - 6176;
    2137  
    2138    if ((q + exp) > 20) {	// x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
    2139      // set invalid flag
    2140      *pfpsf |= INVALID_EXCEPTION;
    2141      // return Integer Indefinite
    2142      res = 0x8000000000000000ull;
    2143      BID_RETURN (res);
    2144    } else if ((q + exp) == 20) {	// x = c(0)c(1)...c(19).c(20)...c(q-1)
    2145      // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
    2146      // so x rounded to an integer may or may not fit in an unsigned 64-bit int
    2147      // the cases that do not fit are identified here; the ones that fit
    2148      // fall through and will be handled with other cases further,
    2149      // under '1 <= q + exp <= 20'
    2150      if (x_sign) {	// if n < 0 and q + exp = 20
    2151        // if n <= -1 then n cannot be converted to uint64 with RZ
    2152        // too large if c(0)c(1)...c(19).c(20)...c(q-1) >= 1
    2153        // <=> 0.c(0)c(1)...c(q-1) * 10^21 >= 0x0a, 1<=q<=34
    2154        // <=> C * 10^(21-q) >= 0x0a, 1<=q<=34
    2155        if (q == 21) {
    2156  	// C >= a 
    2157  	if (C1.w[1] != 0 || C1.w[0] >= 0x0aull) {
    2158  	  // set invalid flag
    2159  	  *pfpsf |= INVALID_EXCEPTION;
    2160  	  // return Integer Indefinite
    2161  	  res = 0x8000000000000000ull;
    2162  	  BID_RETURN (res);
    2163  	}
    2164  	// else cases that can be rounded to 64-bit unsigned int fall through
    2165  	// to '1 <= q + exp <= 20'
    2166        } else {
    2167  	// if 1 <= q <= 20
    2168  	//   C * 10^(21-q) >= a is true because C >= 1 and 10^(21-q) >= 10
    2169  	// if 22 <= q <= 34 => 1 <= q - 21 <= 13
    2170  	//  C >= a * 10^(q-21) is true because C > 2^64 and a*10^(q-21) < 2^64
    2171  	// set invalid flag
    2172  	*pfpsf |= INVALID_EXCEPTION;
    2173  	// return Integer Indefinite
    2174  	res = 0x8000000000000000ull;
    2175  	BID_RETURN (res);
    2176        }
    2177      } else {	// if n > 0 and q + exp = 20
    2178        // if n >= 2^64 then n is too large
    2179        // <=> c(0)c(1)...c(19).c(20)...c(q-1) >= 2^64
    2180        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 >= 2^64
    2181        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 >= 5*2^65
    2182        // <=> C * 10^(21-q) >= 0xa0000000000000000, 1<=q<=34
    2183        if (q == 1) {
    2184  	// C * 10^20 >= 0xa0000000000000000
    2185  	__mul_128x64_to_128 (C, C1.w[0], ten2k128[0]);	// 10^20 * C
    2186  	if (C.w[1] >= 0x0a) {
    2187  	  // actually C.w[1] == 0x0a && C.w[0] >= 0x0000000000000000ull) {
    2188  	  // set invalid flag
    2189  	  *pfpsf |= INVALID_EXCEPTION;
    2190  	  // return Integer Indefinite
    2191  	  res = 0x8000000000000000ull;
    2192  	  BID_RETURN (res);
    2193  	}
    2194  	// else cases that can be rounded to a 64-bit int fall through
    2195  	// to '1 <= q + exp <= 20'
    2196        } else if (q <= 19) {
    2197  	// C * 10^(21-q) >= 0xa0000000000000000
    2198  	__mul_64x64_to_128MACH (C, C1.w[0], ten2k64[21 - q]);
    2199  	if (C.w[1] >= 0x0a) {
    2200  	  // actually C.w[1] == 0x0a && C.w[0] >= 0x0000000000000000ull) {
    2201  	  // set invalid flag
    2202  	  *pfpsf |= INVALID_EXCEPTION;
    2203  	  // return Integer Indefinite
    2204  	  res = 0x8000000000000000ull;
    2205  	  BID_RETURN (res);
    2206  	}
    2207  	// else cases that can be rounded to a 64-bit int fall through
    2208  	// to '1 <= q + exp <= 20'
    2209        } else if (q == 20) {
    2210  	// C >= 0x10000000000000000
    2211  	if (C1.w[1] >= 0x01) {
    2212  	  // actually C1.w[1] == 0x01 && C1.w[0] >= 0x0000000000000000ull) {
    2213  	  // set invalid flag
    2214  	  *pfpsf |= INVALID_EXCEPTION;
    2215  	  // return Integer Indefinite
    2216  	  res = 0x8000000000000000ull;
    2217  	  BID_RETURN (res);
    2218  	}
    2219  	// else cases that can be rounded to a 64-bit int fall through
    2220  	// to '1 <= q + exp <= 20'
    2221        } else if (q == 21) {
    2222  	// C >= 0xa0000000000000000
    2223  	if (C1.w[1] >= 0x0a) {
    2224  	  // actually C1.w[1] == 0x0a && C1.w[0] >= 0x0000000000000000ull) {
    2225  	  // set invalid flag
    2226  	  *pfpsf |= INVALID_EXCEPTION;
    2227  	  // return Integer Indefinite
    2228  	  res = 0x8000000000000000ull;
    2229  	  BID_RETURN (res);
    2230  	}
    2231  	// else cases that can be rounded to a 64-bit int fall through
    2232  	// to '1 <= q + exp <= 20'
    2233        } else {	// if 22 <= q <= 34 => 1 <= q - 21 <= 13
    2234  	// C  >= 10^(q-21) * 0xa0000000000000000 max 44 bits x 68 bits
    2235  	C.w[1] = 0x0a;
    2236  	C.w[0] = 0x0000000000000000ull;
    2237  	__mul_128x64_to_128 (C, ten2k64[q - 21], C);
    2238  	if (C1.w[1] > C.w[1]
    2239  	    || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) {
    2240  	  // set invalid flag
    2241  	  *pfpsf |= INVALID_EXCEPTION;
    2242  	  // return Integer Indefinite
    2243  	  res = 0x8000000000000000ull;
    2244  	  BID_RETURN (res);
    2245  	}
    2246  	// else cases that can be rounded to a 64-bit int fall through
    2247  	// to '1 <= q + exp <= 20'
    2248        }
    2249      }
    2250    }
    2251    // n is not too large to be converted to int64 if -1 < n < 2^64
    2252    // Note: some of the cases tested for above fall through to this point
    2253    if ((q + exp) <= 0) {	// n = +/-0.[0...0]c(0)c(1)...c(q-1)
    2254      // return 0
    2255      res = 0x0000000000000000ull;
    2256      BID_RETURN (res);
    2257    } else {	// if (1 <= q + exp <= 20, 1 <= q <= 34, -33 <= exp <= 19)
    2258      // x <= -1 or 1 <= x < 2^64 so if positive x can be rounded
    2259      // to zero to a 64-bit unsigned signed integer
    2260      if (x_sign) {	// x <= -1
    2261        // set invalid flag
    2262        *pfpsf |= INVALID_EXCEPTION;
    2263        // return Integer Indefinite
    2264        res = 0x8000000000000000ull;
    2265        BID_RETURN (res);
    2266      }
    2267      // 1 <= x < 2^64 so x can be rounded
    2268      // to zero to a 64-bit unsigned integer
    2269      if (exp < 0) {	// 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 20
    2270        ind = -exp;	// 1 <= ind <= 33; ind is a synonym for 'x'
    2271        // chop off ind digits from the lower part of C1
    2272        // C1 fits in 127 bits
    2273        // calculate C* and f*
    2274        // C* is actually floor(C*) in this case
    2275        // C* and f* need shifting and masking, as shown by
    2276        // shiftright128[] and maskhigh128[]
    2277        // 1 <= x <= 33
    2278        // kx = 10^(-x) = ten2mk128[ind - 1]
    2279        // C* = C1 * 10^(-x)
    2280        // the approximation of 10^(-x) was rounded up to 118 bits
    2281        __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
    2282        if (ind - 1 <= 21) {	// 0 <= ind - 1 <= 21
    2283  	Cstar.w[1] = P256.w[3];
    2284  	Cstar.w[0] = P256.w[2];
    2285        } else {	// 22 <= ind - 1 <= 33
    2286  	Cstar.w[1] = 0;
    2287  	Cstar.w[0] = P256.w[3];
    2288        }
    2289        // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
    2290        // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
    2291        // C* = floor(C*) (logical right shift; C has p decimal digits,
    2292        //     correct by Property 1)
    2293        // n = C* * 10^(e+x)
    2294  
    2295        // shift right C* by Ex-128 = shiftright128[ind]
    2296        shift = shiftright128[ind - 1];	// 0 <= shift <= 102
    2297        if (ind - 1 <= 21) {	// 0 <= ind - 1 <= 21
    2298  	Cstar.w[0] =
    2299  	  (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift));
    2300  	// redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
    2301        } else {	// 22 <= ind - 1 <= 33
    2302  	Cstar.w[0] = (Cstar.w[0] >> (shift - 64));	// 2 <= shift - 64 <= 38
    2303        }
    2304        res = Cstar.w[0];	// the result is positive
    2305      } else if (exp == 0) {
    2306        // 1 <= q <= 20, but x < 2^64 - 1/2 so in this case C1.w[1] has to be 0
    2307        // res = C (exact)
    2308        res = C1.w[0];
    2309      } else {
    2310        // if (exp > 0) => 1 <= exp <= 19, 1 <= q < 19, 2 <= q + exp <= 20
    2311        // res = C * 10^exp (exact) - must fit in 64 bits
    2312        res = C1.w[0] * ten2k64[exp];
    2313      }
    2314    }
    2315  }
    2316  
    2317  BID_RETURN (res);
    2318  }
    2319  
    2320  /*****************************************************************************
    2321   *  BID128_to_uint64_xint
    2322   ****************************************************************************/
    2323  
    2324  BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64, bid128_to_uint64_xint,
    2325  					  x)
    2326  
    2327       UINT64 res;
    2328       UINT64 x_sign;
    2329       UINT64 x_exp;
    2330       int exp;			// unbiased exponent
    2331    // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
    2332       BID_UI64DOUBLE tmp1;
    2333       unsigned int x_nr_bits;
    2334       int q, ind, shift;
    2335       UINT128 C1, C;
    2336       UINT128 Cstar;		// C* represents up to 34 decimal digits ~ 113 bits
    2337       UINT256 fstar;
    2338       UINT256 P256;
    2339  
    2340    // unpack x
    2341  x_sign = x.w[1] & MASK_SIGN;	// 0 for positive, MASK_SIGN for negative
    2342  x_exp = x.w[1] & MASK_EXP;	// biased and shifted left 49 bit positions
    2343  C1.w[1] = x.w[1] & MASK_COEFF;
    2344  C1.w[0] = x.w[0];
    2345  
    2346    // check for NaN or Infinity
    2347  if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
    2348      // x is special
    2349  if ((x.w[1] & MASK_NAN) == MASK_NAN) {	// x is NAN
    2350    if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {	// x is SNAN
    2351      // set invalid flag
    2352      *pfpsf |= INVALID_EXCEPTION;
    2353      // return Integer Indefinite
    2354      res = 0x8000000000000000ull;
    2355    } else {	// x is QNaN
    2356      // set invalid flag
    2357      *pfpsf |= INVALID_EXCEPTION;
    2358      // return Integer Indefinite
    2359      res = 0x8000000000000000ull;
    2360    }
    2361    BID_RETURN (res);
    2362  } else {	// x is not a NaN, so it must be infinity
    2363    if (!x_sign) {	// x is +inf
    2364      // set invalid flag
    2365      *pfpsf |= INVALID_EXCEPTION;
    2366      // return Integer Indefinite
    2367      res = 0x8000000000000000ull;
    2368    } else {	// x is -inf
    2369      // set invalid flag
    2370      *pfpsf |= INVALID_EXCEPTION;
    2371      // return Integer Indefinite
    2372      res = 0x8000000000000000ull;
    2373    }
    2374    BID_RETURN (res);
    2375  }
    2376  }
    2377    // check for non-canonical values (after the check for special values)
    2378  if ((C1.w[1] > 0x0001ed09bead87c0ull)
    2379      || (C1.w[1] == 0x0001ed09bead87c0ull
    2380  	&& (C1.w[0] > 0x378d8e63ffffffffull))
    2381      || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
    2382    res = 0x0000000000000000ull;
    2383    BID_RETURN (res);
    2384  } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
    2385    // x is 0
    2386    res = 0x0000000000000000ull;
    2387    BID_RETURN (res);
    2388  } else {	// x is not special and is not zero
    2389  
    2390    // q = nr. of decimal digits in x
    2391    //  determine first the nr. of bits in x
    2392    if (C1.w[1] == 0) {
    2393      if (C1.w[0] >= 0x0020000000000000ull) {	// x >= 2^53
    2394        // split the 64-bit value in two 32-bit halves to avoid rounding errors
    2395        if (C1.w[0] >= 0x0000000100000000ull) {	// x >= 2^32
    2396  	tmp1.d = (double) (C1.w[0] >> 32);	// exact conversion
    2397  	x_nr_bits =
    2398  	  33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    2399        } else {	// x < 2^32
    2400  	tmp1.d = (double) (C1.w[0]);	// exact conversion
    2401  	x_nr_bits =
    2402  	  1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    2403        }
    2404      } else {	// if x < 2^53
    2405        tmp1.d = (double) C1.w[0];	// exact conversion
    2406        x_nr_bits =
    2407  	1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    2408      }
    2409    } else {	// C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
    2410      tmp1.d = (double) C1.w[1];	// exact conversion
    2411      x_nr_bits =
    2412        65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    2413    }
    2414    q = nr_digits[x_nr_bits - 1].digits;
    2415    if (q == 0) {
    2416      q = nr_digits[x_nr_bits - 1].digits1;
    2417      if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
    2418  	|| (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi
    2419  	    && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
    2420        q++;
    2421    }
    2422    exp = (x_exp >> 49) - 6176;
    2423    if ((q + exp) > 20) {	// x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
    2424      // set invalid flag
    2425      *pfpsf |= INVALID_EXCEPTION;
    2426      // return Integer Indefinite
    2427      res = 0x8000000000000000ull;
    2428      BID_RETURN (res);
    2429    } else if ((q + exp) == 20) {	// x = c(0)c(1)...c(19).c(20)...c(q-1)
    2430      // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
    2431      // so x rounded to an integer may or may not fit in an unsigned 64-bit int
    2432      // the cases that do not fit are identified here; the ones that fit
    2433      // fall through and will be handled with other cases further,
    2434      // under '1 <= q + exp <= 20'
    2435      if (x_sign) {	// if n < 0 and q + exp = 20
    2436        // if n <= -1 then n cannot be converted to uint64 with RZ
    2437        // too large if c(0)c(1)...c(19).c(20)...c(q-1) >= 1
    2438        // <=> 0.c(0)c(1)...c(q-1) * 10^21 >= 0x0a, 1<=q<=34
    2439        // <=> C * 10^(21-q) >= 0x0a, 1<=q<=34
    2440        if (q == 21) {
    2441  	// C >= a 
    2442  	if (C1.w[1] != 0 || C1.w[0] >= 0x0aull) {
    2443  	  // set invalid flag
    2444  	  *pfpsf |= INVALID_EXCEPTION;
    2445  	  // return Integer Indefinite
    2446  	  res = 0x8000000000000000ull;
    2447  	  BID_RETURN (res);
    2448  	}
    2449  	// else cases that can be rounded to 64-bit unsigned int fall through
    2450  	// to '1 <= q + exp <= 20'
    2451        } else {
    2452  	// if 1 <= q <= 20
    2453  	//   C * 10^(21-q) >= a is true because C >= 1 and 10^(21-q) >= 10
    2454  	// if 22 <= q <= 34 => 1 <= q - 21 <= 13
    2455  	//  C >= a * 10^(q-21) is true because C > 2^64 and a*10^(q-21) < 2^64
    2456  	// set invalid flag
    2457  	*pfpsf |= INVALID_EXCEPTION;
    2458  	// return Integer Indefinite
    2459  	res = 0x8000000000000000ull;
    2460  	BID_RETURN (res);
    2461        }
    2462      } else {	// if n > 0 and q + exp = 20
    2463        // if n >= 2^64 then n is too large
    2464        // <=> c(0)c(1)...c(19).c(20)...c(q-1) >= 2^64
    2465        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 >= 2^64
    2466        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 >= 5*2^65
    2467        // <=> C * 10^(21-q) >= 0xa0000000000000000, 1<=q<=34
    2468        if (q == 1) {
    2469  	// C * 10^20 >= 0xa0000000000000000
    2470  	__mul_128x64_to_128 (C, C1.w[0], ten2k128[0]);	// 10^20 * C
    2471  	if (C.w[1] >= 0x0a) {
    2472  	  // actually C.w[1] == 0x0a && C.w[0] >= 0x0000000000000000ull) {
    2473  	  // set invalid flag
    2474  	  *pfpsf |= INVALID_EXCEPTION;
    2475  	  // return Integer Indefinite
    2476  	  res = 0x8000000000000000ull;
    2477  	  BID_RETURN (res);
    2478  	}
    2479  	// else cases that can be rounded to a 64-bit int fall through
    2480  	// to '1 <= q + exp <= 20'
    2481        } else if (q <= 19) {
    2482  	// C * 10^(21-q) >= 0xa0000000000000000
    2483  	__mul_64x64_to_128MACH (C, C1.w[0], ten2k64[21 - q]);
    2484  	if (C.w[1] >= 0x0a) {
    2485  	  // actually C.w[1] == 0x0a && C.w[0] >= 0x0000000000000000ull) {
    2486  	  // set invalid flag
    2487  	  *pfpsf |= INVALID_EXCEPTION;
    2488  	  // return Integer Indefinite
    2489  	  res = 0x8000000000000000ull;
    2490  	  BID_RETURN (res);
    2491  	}
    2492  	// else cases that can be rounded to a 64-bit int fall through
    2493  	// to '1 <= q + exp <= 20'
    2494        } else if (q == 20) {
    2495  	// C >= 0x10000000000000000
    2496  	if (C1.w[1] >= 0x01) {
    2497  	  // actually C1.w[1] == 0x01 && C1.w[0] >= 0x0000000000000000ull) {
    2498  	  // set invalid flag
    2499  	  *pfpsf |= INVALID_EXCEPTION;
    2500  	  // return Integer Indefinite
    2501  	  res = 0x8000000000000000ull;
    2502  	  BID_RETURN (res);
    2503  	}
    2504  	// else cases that can be rounded to a 64-bit int fall through
    2505  	// to '1 <= q + exp <= 20'
    2506        } else if (q == 21) {
    2507  	// C >= 0xa0000000000000000
    2508  	if (C1.w[1] >= 0x0a) {
    2509  	  // actually C1.w[1] == 0x0a && C1.w[0] >= 0x0000000000000000ull) {
    2510  	  // set invalid flag
    2511  	  *pfpsf |= INVALID_EXCEPTION;
    2512  	  // return Integer Indefinite
    2513  	  res = 0x8000000000000000ull;
    2514  	  BID_RETURN (res);
    2515  	}
    2516  	// else cases that can be rounded to a 64-bit int fall through
    2517  	// to '1 <= q + exp <= 20'
    2518        } else {	// if 22 <= q <= 34 => 1 <= q - 21 <= 13
    2519  	// C  >= 10^(q-21) * 0xa0000000000000000 max 44 bits x 68 bits
    2520  	C.w[1] = 0x0a;
    2521  	C.w[0] = 0x0000000000000000ull;
    2522  	__mul_128x64_to_128 (C, ten2k64[q - 21], C);
    2523  	if (C1.w[1] > C.w[1]
    2524  	    || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) {
    2525  	  // set invalid flag
    2526  	  *pfpsf |= INVALID_EXCEPTION;
    2527  	  // return Integer Indefinite
    2528  	  res = 0x8000000000000000ull;
    2529  	  BID_RETURN (res);
    2530  	}
    2531  	// else cases that can be rounded to a 64-bit int fall through
    2532  	// to '1 <= q + exp <= 20'
    2533        }
    2534      }
    2535    }
    2536    // n is not too large to be converted to int64 if -1 < n < 2^64
    2537    // Note: some of the cases tested for above fall through to this point
    2538    if ((q + exp) <= 0) {	// n = +/-0.[0...0]c(0)c(1)...c(q-1)
    2539      // set inexact flag
    2540      *pfpsf |= INEXACT_EXCEPTION;
    2541      // return 0
    2542      res = 0x0000000000000000ull;
    2543      BID_RETURN (res);
    2544    } else {	// if (1 <= q + exp <= 20, 1 <= q <= 34, -33 <= exp <= 19)
    2545      // x <= -1 or 1 <= x < 2^64 so if positive x can be rounded
    2546      // to zero to a 64-bit unsigned signed integer
    2547      if (x_sign) {	// x <= -1
    2548        // set invalid flag
    2549        *pfpsf |= INVALID_EXCEPTION;
    2550        // return Integer Indefinite
    2551        res = 0x8000000000000000ull;
    2552        BID_RETURN (res);
    2553      }
    2554      // 1 <= x < 2^64 so x can be rounded
    2555      // to zero to a 64-bit unsigned integer
    2556      if (exp < 0) {	// 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 20
    2557        ind = -exp;	// 1 <= ind <= 33; ind is a synonym for 'x'
    2558        // chop off ind digits from the lower part of C1
    2559        // C1 fits in 127 bits
    2560        // calculate C* and f*
    2561        // C* is actually floor(C*) in this case
    2562        // C* and f* need shifting and masking, as shown by
    2563        // shiftright128[] and maskhigh128[]
    2564        // 1 <= x <= 33
    2565        // kx = 10^(-x) = ten2mk128[ind - 1]
    2566        // C* = C1 * 10^(-x)
    2567        // the approximation of 10^(-x) was rounded up to 118 bits
    2568        __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
    2569        if (ind - 1 <= 21) {	// 0 <= ind - 1 <= 21
    2570  	Cstar.w[1] = P256.w[3];
    2571  	Cstar.w[0] = P256.w[2];
    2572  	fstar.w[3] = 0;
    2573  	fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
    2574  	fstar.w[1] = P256.w[1];
    2575  	fstar.w[0] = P256.w[0];
    2576        } else {	// 22 <= ind - 1 <= 33
    2577  	Cstar.w[1] = 0;
    2578  	Cstar.w[0] = P256.w[3];
    2579  	fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
    2580  	fstar.w[2] = P256.w[2];
    2581  	fstar.w[1] = P256.w[1];
    2582  	fstar.w[0] = P256.w[0];
    2583        }
    2584        // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
    2585        // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
    2586        // C* = floor(C*) (logical right shift; C has p decimal digits,
    2587        //     correct by Property 1)
    2588        // n = C* * 10^(e+x)
    2589  
    2590        // shift right C* by Ex-128 = shiftright128[ind]
    2591        shift = shiftright128[ind - 1];	// 0 <= shift <= 102
    2592        if (ind - 1 <= 21) {	// 0 <= ind - 1 <= 21
    2593  	Cstar.w[0] =
    2594  	  (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift));
    2595  	// redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
    2596        } else {	// 22 <= ind - 1 <= 33
    2597  	Cstar.w[0] = (Cstar.w[0] >> (shift - 64));	// 2 <= shift - 64 <= 38
    2598        }
    2599        // determine inexactness of the rounding of C*
    2600        // if (0 < f* < 10^(-x)) then
    2601        //   the result is exact
    2602        // else // if (f* > T*) then
    2603        //   the result is inexact
    2604        if (ind - 1 <= 2) {
    2605  	if (fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
    2606  	    || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
    2607  		&& fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
    2608  	  // set the inexact flag
    2609  	  *pfpsf |= INEXACT_EXCEPTION;
    2610  	}	// else the result is exact
    2611        } else if (ind - 1 <= 21) {	// if 3 <= ind <= 21
    2612  	if (fstar.w[2] || fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
    2613  	    || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
    2614  		&& fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
    2615  	  // set the inexact flag
    2616  	  *pfpsf |= INEXACT_EXCEPTION;
    2617  	}	// else the result is exact
    2618        } else {	// if 22 <= ind <= 33
    2619  	if (fstar.w[3] || fstar.w[2]
    2620  	    || fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
    2621  	    || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
    2622  		&& fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
    2623  	  // set the inexact flag
    2624  	  *pfpsf |= INEXACT_EXCEPTION;
    2625  	}	// else the result is exact
    2626        }
    2627  
    2628        res = Cstar.w[0];	// the result is positive
    2629      } else if (exp == 0) {
    2630        // 1 <= q <= 20, but x < 2^64 - 1/2 so in this case C1.w[1] has to be 0
    2631        // res = C (exact)
    2632        res = C1.w[0];
    2633      } else {
    2634        // if (exp > 0) => 1 <= exp <= 19, 1 <= q < 19, 2 <= q + exp <= 20
    2635        // res = C * 10^exp (exact) - must fit in 64 bits
    2636        res = C1.w[0] * ten2k64[exp];
    2637      }
    2638    }
    2639  }
    2640  
    2641  BID_RETURN (res);
    2642  }
    2643  
    2644  /*****************************************************************************
    2645   *  BID128_to_uint64_rninta
    2646   ****************************************************************************/
    2647  
    2648  BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64,
    2649  					  bid128_to_uint64_rninta, x)
    2650  
    2651       UINT64 res;
    2652       UINT64 x_sign;
    2653       UINT64 x_exp;
    2654       int exp;			// unbiased exponent
    2655    // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
    2656       UINT64 tmp64;
    2657       BID_UI64DOUBLE tmp1;
    2658       unsigned int x_nr_bits;
    2659       int q, ind, shift;
    2660       UINT128 C1, C;
    2661       UINT128 Cstar;		// C* represents up to 34 decimal digits ~ 113 bits
    2662       UINT256 P256;
    2663  
    2664    // unpack x
    2665  x_sign = x.w[1] & MASK_SIGN;	// 0 for positive, MASK_SIGN for negative
    2666  x_exp = x.w[1] & MASK_EXP;	// biased and shifted left 49 bit positions
    2667  C1.w[1] = x.w[1] & MASK_COEFF;
    2668  C1.w[0] = x.w[0];
    2669  
    2670    // check for NaN or Infinity
    2671  if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
    2672      // x is special
    2673  if ((x.w[1] & MASK_NAN) == MASK_NAN) {	// x is NAN
    2674    if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {	// x is SNAN
    2675      // set invalid flag
    2676      *pfpsf |= INVALID_EXCEPTION;
    2677      // return Integer Indefinite
    2678      res = 0x8000000000000000ull;
    2679    } else {	// x is QNaN
    2680      // set invalid flag
    2681      *pfpsf |= INVALID_EXCEPTION;
    2682      // return Integer Indefinite
    2683      res = 0x8000000000000000ull;
    2684    }
    2685    BID_RETURN (res);
    2686  } else {	// x is not a NaN, so it must be infinity
    2687    if (!x_sign) {	// x is +inf
    2688      // set invalid flag
    2689      *pfpsf |= INVALID_EXCEPTION;
    2690      // return Integer Indefinite
    2691      res = 0x8000000000000000ull;
    2692    } else {	// x is -inf
    2693      // set invalid flag
    2694      *pfpsf |= INVALID_EXCEPTION;
    2695      // return Integer Indefinite
    2696      res = 0x8000000000000000ull;
    2697    }
    2698    BID_RETURN (res);
    2699  }
    2700  }
    2701    // check for non-canonical values (after the check for special values)
    2702  if ((C1.w[1] > 0x0001ed09bead87c0ull)
    2703      || (C1.w[1] == 0x0001ed09bead87c0ull
    2704  	&& (C1.w[0] > 0x378d8e63ffffffffull))
    2705      || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
    2706    res = 0x0000000000000000ull;
    2707    BID_RETURN (res);
    2708  } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
    2709    // x is 0
    2710    res = 0x0000000000000000ull;
    2711    BID_RETURN (res);
    2712  } else {	// x is not special and is not zero
    2713  
    2714    // q = nr. of decimal digits in x
    2715    //  determine first the nr. of bits in x
    2716    if (C1.w[1] == 0) {
    2717      if (C1.w[0] >= 0x0020000000000000ull) {	// x >= 2^53
    2718        // split the 64-bit value in two 32-bit halves to avoid rounding errors
    2719        if (C1.w[0] >= 0x0000000100000000ull) {	// x >= 2^32
    2720  	tmp1.d = (double) (C1.w[0] >> 32);	// exact conversion
    2721  	x_nr_bits =
    2722  	  33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    2723        } else {	// x < 2^32
    2724  	tmp1.d = (double) (C1.w[0]);	// exact conversion
    2725  	x_nr_bits =
    2726  	  1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    2727        }
    2728      } else {	// if x < 2^53
    2729        tmp1.d = (double) C1.w[0];	// exact conversion
    2730        x_nr_bits =
    2731  	1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    2732      }
    2733    } else {	// C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
    2734      tmp1.d = (double) C1.w[1];	// exact conversion
    2735      x_nr_bits =
    2736        65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    2737    }
    2738    q = nr_digits[x_nr_bits - 1].digits;
    2739    if (q == 0) {
    2740      q = nr_digits[x_nr_bits - 1].digits1;
    2741      if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
    2742  	|| (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi
    2743  	    && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
    2744        q++;
    2745    }
    2746    exp = (x_exp >> 49) - 6176;
    2747    if ((q + exp) > 20) {	// x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
    2748      // set invalid flag
    2749      *pfpsf |= INVALID_EXCEPTION;
    2750      // return Integer Indefinite
    2751      res = 0x8000000000000000ull;
    2752      BID_RETURN (res);
    2753    } else if ((q + exp) == 20) {	// x = c(0)c(1)...c(19).c(20)...c(q-1)
    2754      // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
    2755      // so x rounded to an integer may or may not fit in an unsigned 64-bit int
    2756      // the cases that do not fit are identified here; the ones that fit
    2757      // fall through and will be handled with other cases further,
    2758      // under '1 <= q + exp <= 20'
    2759      if (x_sign) {	// if n < 0 and q + exp = 20
    2760        // if n <= -1/2 then n cannot be converted to uint64 with RN
    2761        // too large if c(0)c(1)...c(19).c(20)...c(q-1) >= 1/2
    2762        // <=> 0.c(0)c(1)...c(q-1) * 10^21 >= 0x05, 1<=q<=34
    2763        // <=> C * 10^(21-q) >= 0x05, 1<=q<=34
    2764        if (q == 21) {
    2765  	// C >= 5 
    2766  	if (C1.w[1] != 0 || C1.w[0] >= 0x05ull) {
    2767  	  // set invalid flag
    2768  	  *pfpsf |= INVALID_EXCEPTION;
    2769  	  // return Integer Indefinite
    2770  	  res = 0x8000000000000000ull;
    2771  	  BID_RETURN (res);
    2772  	}
    2773  	// else cases that can be rounded to 64-bit unsigned int fall through
    2774  	// to '1 <= q + exp <= 20'
    2775        } else {
    2776  	// if 1 <= q <= 20
    2777  	//   C * 10^(21-q) >= 5 is true because C >= 1 and 10^(21-q) >= 10
    2778  	// if 22 <= q <= 34 => 1 <= q - 21 <= 13
    2779  	//  C >= 5 * 10^(q-21) is true because C > 2^64 and 5*10^(q-21) < 2^64
    2780  	// set invalid flag
    2781  	*pfpsf |= INVALID_EXCEPTION;
    2782  	// return Integer Indefinite
    2783  	res = 0x8000000000000000ull;
    2784  	BID_RETURN (res);
    2785        }
    2786      } else {	// if n > 0 and q + exp = 20
    2787        // if n >= 2^64 - 1/2 then n is too large
    2788        // <=> c(0)c(1)...c(19).c(20)...c(q-1) >= 2^64-1/2
    2789        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 >= 2^64-1/2
    2790        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 >= 5*(2^65-1)
    2791        // <=> C * 10^(21-q) >= 0x9fffffffffffffffb, 1<=q<=34
    2792        if (q == 1) {
    2793  	// C * 10^20 >= 0x9fffffffffffffffb
    2794  	__mul_128x64_to_128 (C, C1.w[0], ten2k128[0]);	// 10^20 * C
    2795  	if (C.w[1] > 0x09 || (C.w[1] == 0x09
    2796  			      && C.w[0] >= 0xfffffffffffffffbull)) {
    2797  	  // set invalid flag
    2798  	  *pfpsf |= INVALID_EXCEPTION;
    2799  	  // return Integer Indefinite
    2800  	  res = 0x8000000000000000ull;
    2801  	  BID_RETURN (res);
    2802  	}
    2803  	// else cases that can be rounded to a 64-bit int fall through
    2804  	// to '1 <= q + exp <= 20'
    2805        } else if (q <= 19) {
    2806  	// C * 10^(21-q) >= 0x9fffffffffffffffb
    2807  	__mul_64x64_to_128MACH (C, C1.w[0], ten2k64[21 - q]);
    2808  	if (C.w[1] > 0x09 || (C.w[1] == 0x09
    2809  			      && C.w[0] >= 0xfffffffffffffffbull)) {
    2810  	  // set invalid flag
    2811  	  *pfpsf |= INVALID_EXCEPTION;
    2812  	  // return Integer Indefinite
    2813  	  res = 0x8000000000000000ull;
    2814  	  BID_RETURN (res);
    2815  	}
    2816  	// else cases that can be rounded to a 64-bit int fall through
    2817  	// to '1 <= q + exp <= 20'
    2818        } else if (q == 20) {
    2819  	// C * 10 >= 0x9fffffffffffffffb <=> C * 2 > 1ffffffffffffffff
    2820  	C.w[0] = C1.w[0] + C1.w[0];
    2821  	C.w[1] = C1.w[1] + C1.w[1];
    2822  	if (C.w[0] < C1.w[0])
    2823  	  C.w[1]++;
    2824  	if (C.w[1] > 0x01 || (C.w[1] == 0x01
    2825  			      && C.w[0] >= 0xffffffffffffffffull)) {
    2826  	  // set invalid flag
    2827  	  *pfpsf |= INVALID_EXCEPTION;
    2828  	  // return Integer Indefinite
    2829  	  res = 0x8000000000000000ull;
    2830  	  BID_RETURN (res);
    2831  	}
    2832  	// else cases that can be rounded to a 64-bit int fall through
    2833  	// to '1 <= q + exp <= 20'
    2834        } else if (q == 21) {
    2835  	// C >= 0x9fffffffffffffffb
    2836  	if (C1.w[1] > 0x09 || (C1.w[1] == 0x09
    2837  			       && C1.w[0] >= 0xfffffffffffffffbull)) {
    2838  	  // set invalid flag
    2839  	  *pfpsf |= INVALID_EXCEPTION;
    2840  	  // return Integer Indefinite
    2841  	  res = 0x8000000000000000ull;
    2842  	  BID_RETURN (res);
    2843  	}
    2844  	// else cases that can be rounded to a 64-bit int fall through
    2845  	// to '1 <= q + exp <= 20'
    2846        } else {	// if 22 <= q <= 34 => 1 <= q - 21 <= 13
    2847  	// C  >= 10^(q-21) * 0x9fffffffffffffffb max 44 bits x 68 bits
    2848  	C.w[1] = 0x09;
    2849  	C.w[0] = 0xfffffffffffffffbull;
    2850  	__mul_128x64_to_128 (C, ten2k64[q - 21], C);
    2851  	if (C1.w[1] > C.w[1]
    2852  	    || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) {
    2853  	  // set invalid flag
    2854  	  *pfpsf |= INVALID_EXCEPTION;
    2855  	  // return Integer Indefinite
    2856  	  res = 0x8000000000000000ull;
    2857  	  BID_RETURN (res);
    2858  	}
    2859  	// else cases that can be rounded to a 64-bit int fall through
    2860  	// to '1 <= q + exp <= 20'
    2861        }
    2862      }
    2863    }
    2864    // n is not too large to be converted to int64 if -1/2 < n < 2^64 - 1/2
    2865    // Note: some of the cases tested for above fall through to this point
    2866    if ((q + exp) < 0) {	// n = +/-0.0...c(0)c(1)...c(q-1)
    2867      // return 0
    2868      res = 0x0000000000000000ull;
    2869      BID_RETURN (res);
    2870    } else if ((q + exp) == 0) {	// n = +/-0.c(0)c(1)...c(q-1)
    2871      // if 0.c(0)c(1)...c(q-1) < 0.5 <=> c(0)c(1)...c(q-1) < 5 * 10^(q-1)
    2872      //   res = 0
    2873      // else if x > 0
    2874      //   res = +1
    2875      // else // if x < 0
    2876      //   invalid exc
    2877      ind = q - 1;
    2878      if (ind <= 18) {	// 0 <= ind <= 18
    2879        if ((C1.w[1] == 0) && (C1.w[0] < midpoint64[ind])) {
    2880  	res = 0x0000000000000000ull;	// return 0
    2881        } else if (!x_sign) {	// n > 0
    2882  	res = 0x00000001;	// return +1
    2883        } else {
    2884  	// set invalid flag
    2885  	*pfpsf |= INVALID_EXCEPTION;
    2886  	// return Integer Indefinite
    2887  	res = 0x8000000000000000ull;
    2888  	BID_RETURN (res);
    2889        }
    2890      } else {	// 19 <= ind <= 33
    2891        if ((C1.w[1] < midpoint128[ind - 19].w[1])
    2892  	  || ((C1.w[1] == midpoint128[ind - 19].w[1])
    2893  	      && (C1.w[0] < midpoint128[ind - 19].w[0]))) {
    2894  	res = 0x0000000000000000ull;	// return 0
    2895        } else if (!x_sign) {	// n > 0
    2896  	res = 0x00000001;	// return +1
    2897        } else {
    2898  	// set invalid flag
    2899  	*pfpsf |= INVALID_EXCEPTION;
    2900  	// return Integer Indefinite
    2901  	res = 0x8000000000000000ull;
    2902  	BID_RETURN (res);
    2903        }
    2904      }
    2905    } else {	// if (1 <= q + exp <= 20, 1 <= q <= 34, -33 <= exp <= 19)
    2906      // x <= -1 or 1 <= x < 2^64-1/2 so if positive x can be rounded
    2907      // to nearest to a 64-bit unsigned signed integer
    2908      if (x_sign) {	// x <= -1
    2909        // set invalid flag
    2910        *pfpsf |= INVALID_EXCEPTION;
    2911        // return Integer Indefinite
    2912        res = 0x8000000000000000ull;
    2913        BID_RETURN (res);
    2914      }
    2915      // 1 <= x < 2^64-1/2 so x can be rounded
    2916      // to nearest to a 64-bit unsigned integer
    2917      if (exp < 0) {	// 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 20
    2918        ind = -exp;	// 1 <= ind <= 33; ind is a synonym for 'x'
    2919        // chop off ind digits from the lower part of C1
    2920        // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 127 bits
    2921        tmp64 = C1.w[0];
    2922        if (ind <= 19) {
    2923  	C1.w[0] = C1.w[0] + midpoint64[ind - 1];
    2924        } else {
    2925  	C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
    2926  	C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
    2927        }
    2928        if (C1.w[0] < tmp64)
    2929  	C1.w[1]++;
    2930        // calculate C* and f*
    2931        // C* is actually floor(C*) in this case
    2932        // C* and f* need shifting and masking, as shown by
    2933        // shiftright128[] and maskhigh128[]
    2934        // 1 <= x <= 33
    2935        // kx = 10^(-x) = ten2mk128[ind - 1]
    2936        // C* = (C1 + 1/2 * 10^x) * 10^(-x)
    2937        // the approximation of 10^(-x) was rounded up to 118 bits
    2938        __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
    2939        if (ind - 1 <= 21) {	// 0 <= ind - 1 <= 21
    2940  	Cstar.w[1] = P256.w[3];
    2941  	Cstar.w[0] = P256.w[2];
    2942        } else {	// 22 <= ind - 1 <= 33
    2943  	Cstar.w[1] = 0;
    2944  	Cstar.w[0] = P256.w[3];
    2945        }
    2946        // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
    2947        // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
    2948        // if (0 < f* < 10^(-x)) then the result is a midpoint
    2949        //   if floor(C*) is even then C* = floor(C*) - logical right
    2950        //       shift; C* has p decimal digits, correct by Prop. 1)
    2951        //   else if floor(C*) is odd C* = floor(C*)-1 (logical right
    2952        //       shift; C* has p decimal digits, correct by Pr. 1)
    2953        // else
    2954        //   C* = floor(C*) (logical right shift; C has p decimal digits,
    2955        //       correct by Property 1)
    2956        // n = C* * 10^(e+x)
    2957  
    2958        // shift right C* by Ex-128 = shiftright128[ind]
    2959        shift = shiftright128[ind - 1];	// 0 <= shift <= 102
    2960        if (ind - 1 <= 21) {	// 0 <= ind - 1 <= 21
    2961  	Cstar.w[0] =
    2962  	  (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift));
    2963  	// redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
    2964        } else {	// 22 <= ind - 1 <= 33
    2965  	Cstar.w[0] = (Cstar.w[0] >> (shift - 64));	// 2 <= shift - 64 <= 38
    2966        }
    2967  
    2968        // if the result was a midpoint it was rounded away from zero
    2969        res = Cstar.w[0];	// the result is positive
    2970      } else if (exp == 0) {
    2971        // 1 <= q <= 20, but x < 2^64 - 1/2 so in this case C1.w[1] has to be 0
    2972        // res = C (exact)
    2973        res = C1.w[0];
    2974      } else {
    2975        // if (exp > 0) => 1 <= exp <= 19, 1 <= q < 19, 2 <= q + exp <= 20
    2976        // res = C * 10^exp (exact) - must fit in 64 bits
    2977        res = C1.w[0] * ten2k64[exp];
    2978      }
    2979    }
    2980  }
    2981  
    2982  BID_RETURN (res);
    2983  }
    2984  
    2985  /*****************************************************************************
    2986   *  BID128_to_uint64_xrninta
    2987   ****************************************************************************/
    2988  
    2989  BID128_FUNCTION_ARG1_NORND_CUSTOMRESTYPE (UINT64,
    2990  					  bid128_to_uint64_xrninta, x)
    2991  
    2992       UINT64 res;
    2993       UINT64 x_sign;
    2994       UINT64 x_exp;
    2995       int exp;			// unbiased exponent
    2996    // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
    2997       UINT64 tmp64, tmp64A;
    2998       BID_UI64DOUBLE tmp1;
    2999       unsigned int x_nr_bits;
    3000       int q, ind, shift;
    3001       UINT128 C1, C;
    3002       UINT128 Cstar;		// C* represents up to 34 decimal digits ~ 113 bits
    3003       UINT256 fstar;
    3004       UINT256 P256;
    3005  
    3006    // unpack x
    3007  x_sign = x.w[1] & MASK_SIGN;	// 0 for positive, MASK_SIGN for negative
    3008  x_exp = x.w[1] & MASK_EXP;	// biased and shifted left 49 bit positions
    3009  C1.w[1] = x.w[1] & MASK_COEFF;
    3010  C1.w[0] = x.w[0];
    3011  
    3012    // check for NaN or Infinity
    3013  if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
    3014      // x is special
    3015  if ((x.w[1] & MASK_NAN) == MASK_NAN) {	// x is NAN
    3016    if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {	// x is SNAN
    3017      // set invalid flag
    3018      *pfpsf |= INVALID_EXCEPTION;
    3019      // return Integer Indefinite
    3020      res = 0x8000000000000000ull;
    3021    } else {	// x is QNaN
    3022      // set invalid flag
    3023      *pfpsf |= INVALID_EXCEPTION;
    3024      // return Integer Indefinite
    3025      res = 0x8000000000000000ull;
    3026    }
    3027    BID_RETURN (res);
    3028  } else {	// x is not a NaN, so it must be infinity
    3029    if (!x_sign) {	// x is +inf
    3030      // set invalid flag
    3031      *pfpsf |= INVALID_EXCEPTION;
    3032      // return Integer Indefinite
    3033      res = 0x8000000000000000ull;
    3034    } else {	// x is -inf
    3035      // set invalid flag
    3036      *pfpsf |= INVALID_EXCEPTION;
    3037      // return Integer Indefinite
    3038      res = 0x8000000000000000ull;
    3039    }
    3040    BID_RETURN (res);
    3041  }
    3042  }
    3043    // check for non-canonical values (after the check for special values)
    3044  if ((C1.w[1] > 0x0001ed09bead87c0ull)
    3045      || (C1.w[1] == 0x0001ed09bead87c0ull
    3046  	&& (C1.w[0] > 0x378d8e63ffffffffull))
    3047      || ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull)) {
    3048    res = 0x0000000000000000ull;
    3049    BID_RETURN (res);
    3050  } else if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
    3051    // x is 0
    3052    res = 0x0000000000000000ull;
    3053    BID_RETURN (res);
    3054  } else {	// x is not special and is not zero
    3055  
    3056    // q = nr. of decimal digits in x
    3057    //  determine first the nr. of bits in x
    3058    if (C1.w[1] == 0) {
    3059      if (C1.w[0] >= 0x0020000000000000ull) {	// x >= 2^53
    3060        // split the 64-bit value in two 32-bit halves to avoid rounding errors
    3061        if (C1.w[0] >= 0x0000000100000000ull) {	// x >= 2^32
    3062  	tmp1.d = (double) (C1.w[0] >> 32);	// exact conversion
    3063  	x_nr_bits =
    3064  	  33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    3065        } else {	// x < 2^32
    3066  	tmp1.d = (double) (C1.w[0]);	// exact conversion
    3067  	x_nr_bits =
    3068  	  1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    3069        }
    3070      } else {	// if x < 2^53
    3071        tmp1.d = (double) C1.w[0];	// exact conversion
    3072        x_nr_bits =
    3073  	1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    3074      }
    3075    } else {	// C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
    3076      tmp1.d = (double) C1.w[1];	// exact conversion
    3077      x_nr_bits =
    3078        65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    3079    }
    3080    q = nr_digits[x_nr_bits - 1].digits;
    3081    if (q == 0) {
    3082      q = nr_digits[x_nr_bits - 1].digits1;
    3083      if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
    3084  	|| (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi
    3085  	    && C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
    3086        q++;
    3087    }
    3088    exp = (x_exp >> 49) - 6176;
    3089  
    3090    if ((q + exp) > 20) {	// x >= 10^20 ~= 2^66.45... (cannot fit in 64 bits)
    3091      // set invalid flag
    3092      *pfpsf |= INVALID_EXCEPTION;
    3093      // return Integer Indefinite
    3094      res = 0x8000000000000000ull;
    3095      BID_RETURN (res);
    3096    } else if ((q + exp) == 20) {	// x = c(0)c(1)...c(19).c(20)...c(q-1)
    3097      // in this case 2^63.11... ~= 10^19 <= x < 10^20 ~= 2^66.43...
    3098      // so x rounded to an integer may or may not fit in an unsigned 64-bit int
    3099      // the cases that do not fit are identified here; the ones that fit
    3100      // fall through and will be handled with other cases further,
    3101      // under '1 <= q + exp <= 20'
    3102      if (x_sign) {	// if n < 0 and q + exp = 20
    3103        // if n <= -1/2 then n cannot be converted to uint64 with RN
    3104        // too large if c(0)c(1)...c(19).c(20)...c(q-1) >= 1/2
    3105        // <=> 0.c(0)c(1)...c(q-1) * 10^21 >= 0x05, 1<=q<=34
    3106        // <=> C * 10^(21-q) >= 0x05, 1<=q<=34
    3107        if (q == 21) {
    3108  	// C >= 5 
    3109  	if (C1.w[1] != 0 || C1.w[0] >= 0x05ull) {
    3110  	  // set invalid flag
    3111  	  *pfpsf |= INVALID_EXCEPTION;
    3112  	  // return Integer Indefinite
    3113  	  res = 0x8000000000000000ull;
    3114  	  BID_RETURN (res);
    3115  	}
    3116  	// else cases that can be rounded to 64-bit unsigned int fall through
    3117  	// to '1 <= q + exp <= 20'
    3118        } else {
    3119  	// if 1 <= q <= 20
    3120  	//   C * 10^(21-q) >= 5 is true because C >= 1 and 10^(21-q) >= 10
    3121  	// if 22 <= q <= 34 => 1 <= q - 21 <= 13
    3122  	//  C >= 5 * 10^(q-21) is true because C > 2^64 and 5*10^(q-21) < 2^64
    3123  	// set invalid flag
    3124  	*pfpsf |= INVALID_EXCEPTION;
    3125  	// return Integer Indefinite
    3126  	res = 0x8000000000000000ull;
    3127  	BID_RETURN (res);
    3128        }
    3129      } else {	// if n > 0 and q + exp = 20
    3130        // if n >= 2^64 - 1/2 then n is too large
    3131        // <=> c(0)c(1)...c(19).c(20)...c(q-1) >= 2^64-1/2
    3132        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^20 >= 2^64-1/2
    3133        // <=> 0.c(0)c(1)...c(19)c(20)...c(q-1) * 10^21 >= 5*(2^65-1)
    3134        // <=> C * 10^(21-q) >= 0x9fffffffffffffffb, 1<=q<=34
    3135        if (q == 1) {
    3136  	// C * 10^20 >= 0x9fffffffffffffffb
    3137  	__mul_128x64_to_128 (C, C1.w[0], ten2k128[0]);	// 10^20 * C
    3138  	if (C.w[1] > 0x09 || (C.w[1] == 0x09
    3139  			      && C.w[0] >= 0xfffffffffffffffbull)) {
    3140  	  // set invalid flag
    3141  	  *pfpsf |= INVALID_EXCEPTION;
    3142  	  // return Integer Indefinite
    3143  	  res = 0x8000000000000000ull;
    3144  	  BID_RETURN (res);
    3145  	}
    3146  	// else cases that can be rounded to a 64-bit int fall through
    3147  	// to '1 <= q + exp <= 20'
    3148        } else if (q <= 19) {
    3149  	// C * 10^(21-q) >= 0x9fffffffffffffffb
    3150  	__mul_64x64_to_128MACH (C, C1.w[0], ten2k64[21 - q]);
    3151  	if (C.w[1] > 0x09 || (C.w[1] == 0x09
    3152  			      && C.w[0] >= 0xfffffffffffffffbull)) {
    3153  	  // set invalid flag
    3154  	  *pfpsf |= INVALID_EXCEPTION;
    3155  	  // return Integer Indefinite
    3156  	  res = 0x8000000000000000ull;
    3157  	  BID_RETURN (res);
    3158  	}
    3159  	// else cases that can be rounded to a 64-bit int fall through
    3160  	// to '1 <= q + exp <= 20'
    3161        } else if (q == 20) {
    3162  	// C * 10 >= 0x9fffffffffffffffb <=> C * 2 > 1ffffffffffffffff
    3163  	C.w[0] = C1.w[0] + C1.w[0];
    3164  	C.w[1] = C1.w[1] + C1.w[1];
    3165  	if (C.w[0] < C1.w[0])
    3166  	  C.w[1]++;
    3167  	if (C.w[1] > 0x01 || (C.w[1] == 0x01
    3168  			      && C.w[0] >= 0xffffffffffffffffull)) {
    3169  	  // set invalid flag
    3170  	  *pfpsf |= INVALID_EXCEPTION;
    3171  	  // return Integer Indefinite
    3172  	  res = 0x8000000000000000ull;
    3173  	  BID_RETURN (res);
    3174  	}
    3175  	// else cases that can be rounded to a 64-bit int fall through
    3176  	// to '1 <= q + exp <= 20'
    3177        } else if (q == 21) {
    3178  	// C >= 0x9fffffffffffffffb
    3179  	if (C1.w[1] > 0x09 || (C1.w[1] == 0x09
    3180  			       && C1.w[0] >= 0xfffffffffffffffbull)) {
    3181  	  // set invalid flag
    3182  	  *pfpsf |= INVALID_EXCEPTION;
    3183  	  // return Integer Indefinite
    3184  	  res = 0x8000000000000000ull;
    3185  	  BID_RETURN (res);
    3186  	}
    3187  	// else cases that can be rounded to a 64-bit int fall through
    3188  	// to '1 <= q + exp <= 20'
    3189        } else {	// if 22 <= q <= 34 => 1 <= q - 21 <= 13
    3190  	// C  >= 10^(q-21) * 0x9fffffffffffffffb max 44 bits x 68 bits
    3191  	C.w[1] = 0x09;
    3192  	C.w[0] = 0xfffffffffffffffbull;
    3193  	__mul_128x64_to_128 (C, ten2k64[q - 21], C);
    3194  	if (C1.w[1] > C.w[1]
    3195  	    || (C1.w[1] == C.w[1] && C1.w[0] >= C.w[0])) {
    3196  	  // set invalid flag
    3197  	  *pfpsf |= INVALID_EXCEPTION;
    3198  	  // return Integer Indefinite
    3199  	  res = 0x8000000000000000ull;
    3200  	  BID_RETURN (res);
    3201  	}
    3202  	// else cases that can be rounded to a 64-bit int fall through
    3203  	// to '1 <= q + exp <= 20'
    3204        }
    3205      }
    3206    }
    3207    // n is not too large to be converted to int64 if -1/2 < n < 2^64 - 1/2
    3208    // Note: some of the cases tested for above fall through to this point
    3209    if ((q + exp) < 0) {	// n = +/-0.0...c(0)c(1)...c(q-1)
    3210      // set inexact flag
    3211      *pfpsf |= INEXACT_EXCEPTION;
    3212      // return 0
    3213      res = 0x0000000000000000ull;
    3214      BID_RETURN (res);
    3215    } else if ((q + exp) == 0) {	// n = +/-0.c(0)c(1)...c(q-1)
    3216      // if 0.c(0)c(1)...c(q-1) < 0.5 <=> c(0)c(1)...c(q-1) < 5 * 10^(q-1)
    3217      //   res = 0
    3218      // else if x > 0
    3219      //   res = +1
    3220      // else // if x < 0
    3221      //   invalid exc
    3222      ind = q - 1;
    3223      if (ind <= 18) {	// 0 <= ind <= 18
    3224        if ((C1.w[1] == 0) && (C1.w[0] < midpoint64[ind])) {
    3225  	res = 0x0000000000000000ull;	// return 0
    3226        } else if (!x_sign) {	// n > 0
    3227  	res = 0x00000001;	// return +1
    3228        } else {
    3229  	res = 0x8000000000000000ull;
    3230  	// set invalid flag
    3231  	*pfpsf |= INVALID_EXCEPTION;
    3232  	// return Integer Indefinite
    3233  	res = 0x8000000000000000ull;
    3234  	BID_RETURN (res);
    3235        }
    3236      } else {	// 19 <= ind <= 33
    3237        if ((C1.w[1] < midpoint128[ind - 19].w[1])
    3238  	  || ((C1.w[1] == midpoint128[ind - 19].w[1])
    3239  	      && (C1.w[0] < midpoint128[ind - 19].w[0]))) {
    3240  	res = 0x0000000000000000ull;	// return 0
    3241        } else if (!x_sign) {	// n > 0
    3242  	res = 0x00000001;	// return +1
    3243        } else {
    3244  	res = 0x8000000000000000ull;
    3245  	*pfpsf |= INVALID_EXCEPTION;
    3246  	// return Integer Indefinite
    3247  	res = 0x8000000000000000ull;
    3248  	BID_RETURN (res);
    3249        }
    3250      }
    3251      // set inexact flag
    3252      *pfpsf |= INEXACT_EXCEPTION;
    3253    } else {	// if (1 <= q + exp <= 20, 1 <= q <= 34, -33 <= exp <= 19)
    3254      // x <= -1 or 1 <= x < 2^64-1/2 so if positive x can be rounded
    3255      // to nearest to a 64-bit unsigned signed integer
    3256      if (x_sign) {	// x <= -1
    3257        // set invalid flag
    3258        *pfpsf |= INVALID_EXCEPTION;
    3259        // return Integer Indefinite
    3260        res = 0x8000000000000000ull;
    3261        BID_RETURN (res);
    3262      }
    3263      // 1 <= x < 2^64-1/2 so x can be rounded
    3264      // to nearest to a 64-bit unsigned integer
    3265      if (exp < 0) {	// 2 <= q <= 34, -33 <= exp <= -1, 1 <= q + exp <= 20
    3266        ind = -exp;	// 1 <= ind <= 33; ind is a synonym for 'x'
    3267        // chop off ind digits from the lower part of C1
    3268        // C1 = C1 + 1/2 * 10^ind where the result C1 fits in 127 bits
    3269        tmp64 = C1.w[0];
    3270        if (ind <= 19) {
    3271  	C1.w[0] = C1.w[0] + midpoint64[ind - 1];
    3272        } else {
    3273  	C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
    3274  	C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
    3275        }
    3276        if (C1.w[0] < tmp64)
    3277  	C1.w[1]++;
    3278        // calculate C* and f*
    3279        // C* is actually floor(C*) in this case
    3280        // C* and f* need shifting and masking, as shown by
    3281        // shiftright128[] and maskhigh128[]
    3282        // 1 <= x <= 33
    3283        // kx = 10^(-x) = ten2mk128[ind - 1]
    3284        // C* = (C1 + 1/2 * 10^x) * 10^(-x)
    3285        // the approximation of 10^(-x) was rounded up to 118 bits
    3286        __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
    3287        if (ind - 1 <= 21) {	// 0 <= ind - 1 <= 21
    3288  	Cstar.w[1] = P256.w[3];
    3289  	Cstar.w[0] = P256.w[2];
    3290  	fstar.w[3] = 0;
    3291  	fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
    3292  	fstar.w[1] = P256.w[1];
    3293  	fstar.w[0] = P256.w[0];
    3294        } else {	// 22 <= ind - 1 <= 33
    3295  	Cstar.w[1] = 0;
    3296  	Cstar.w[0] = P256.w[3];
    3297  	fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
    3298  	fstar.w[2] = P256.w[2];
    3299  	fstar.w[1] = P256.w[1];
    3300  	fstar.w[0] = P256.w[0];
    3301        }
    3302        // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
    3303        // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
    3304        // if (0 < f* < 10^(-x)) then the result is a midpoint
    3305        //   if floor(C*) is even then C* = floor(C*) - logical right
    3306        //       shift; C* has p decimal digits, correct by Prop. 1)
    3307        //   else if floor(C*) is odd C* = floor(C*)-1 (logical right
    3308        //       shift; C* has p decimal digits, correct by Pr. 1)
    3309        // else
    3310        //   C* = floor(C*) (logical right shift; C has p decimal digits,
    3311        //       correct by Property 1)
    3312        // n = C* * 10^(e+x)
    3313  
    3314        // shift right C* by Ex-128 = shiftright128[ind]
    3315        shift = shiftright128[ind - 1];	// 0 <= shift <= 102
    3316        if (ind - 1 <= 21) {	// 0 <= ind - 1 <= 21
    3317  	Cstar.w[0] =
    3318  	  (Cstar.w[0] >> shift) | (Cstar.w[1] << (64 - shift));
    3319  	// redundant, it will be 0! Cstar.w[1] = (Cstar.w[1] >> shift);
    3320        } else {	// 22 <= ind - 1 <= 33
    3321  	Cstar.w[0] = (Cstar.w[0] >> (shift - 64));	// 2 <= shift - 64 <= 38
    3322        }
    3323        // determine inexactness of the rounding of C*
    3324        // if (0 < f* - 1/2 < 10^(-x)) then
    3325        //   the result is exact
    3326        // else // if (f* - 1/2 > T*) then
    3327        //   the result is inexact
    3328        if (ind - 1 <= 2) {
    3329  	if (fstar.w[1] > 0x8000000000000000ull ||
    3330  	    (fstar.w[1] == 0x8000000000000000ull
    3331  	     && fstar.w[0] > 0x0ull)) {
    3332  	  // f* > 1/2 and the result may be exact
    3333  	  tmp64 = fstar.w[1] - 0x8000000000000000ull;	// f* - 1/2
    3334  	  if (tmp64 > ten2mk128trunc[ind - 1].w[1]
    3335  	      || (tmp64 == ten2mk128trunc[ind - 1].w[1]
    3336  		  && fstar.w[0] >= ten2mk128trunc[ind - 1].w[0])) {
    3337  	    // set the inexact flag
    3338  	    *pfpsf |= INEXACT_EXCEPTION;
    3339  	  }	// else the result is exact
    3340  	} else {	// the result is inexact; f2* <= 1/2
    3341  	  // set the inexact flag
    3342  	  *pfpsf |= INEXACT_EXCEPTION;
    3343  	}
    3344        } else if (ind - 1 <= 21) {	// if 3 <= ind <= 21
    3345  	if (fstar.w[3] > 0x0 ||
    3346  	    (fstar.w[3] == 0x0 && fstar.w[2] > onehalf128[ind - 1]) ||
    3347  	    (fstar.w[3] == 0x0 && fstar.w[2] == onehalf128[ind - 1] &&
    3348  	     (fstar.w[1] || fstar.w[0]))) {
    3349  	  // f2* > 1/2 and the result may be exact
    3350  	  // Calculate f2* - 1/2
    3351  	  tmp64 = fstar.w[2] - onehalf128[ind - 1];
    3352  	  tmp64A = fstar.w[3];
    3353  	  if (tmp64 > fstar.w[2])
    3354  	    tmp64A--;
    3355  	  if (tmp64A || tmp64
    3356  	      || fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
    3357  	      || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
    3358  		  && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
    3359  	    // set the inexact flag
    3360  	    *pfpsf |= INEXACT_EXCEPTION;
    3361  	  }	// else the result is exact
    3362  	} else {	// the result is inexact; f2* <= 1/2
    3363  	  // set the inexact flag
    3364  	  *pfpsf |= INEXACT_EXCEPTION;
    3365  	}
    3366        } else {	// if 22 <= ind <= 33
    3367  	if (fstar.w[3] > onehalf128[ind - 1] ||
    3368  	    (fstar.w[3] == onehalf128[ind - 1] &&
    3369  	     (fstar.w[2] || fstar.w[1] || fstar.w[0]))) {
    3370  	  // f2* > 1/2 and the result may be exact
    3371  	  // Calculate f2* - 1/2
    3372  	  tmp64 = fstar.w[3] - onehalf128[ind - 1];
    3373  	  if (tmp64 || fstar.w[2]
    3374  	      || fstar.w[1] > ten2mk128trunc[ind - 1].w[1]
    3375  	      || (fstar.w[1] == ten2mk128trunc[ind - 1].w[1]
    3376  		  && fstar.w[0] > ten2mk128trunc[ind - 1].w[0])) {
    3377  	    // set the inexact flag
    3378  	    *pfpsf |= INEXACT_EXCEPTION;
    3379  	  }	// else the result is exact
    3380  	} else {	// the result is inexact; f2* <= 1/2
    3381  	  // set the inexact flag
    3382  	  *pfpsf |= INEXACT_EXCEPTION;
    3383  	}
    3384        }
    3385  
    3386        // if the result was a midpoint it was rounded away from zero
    3387        res = Cstar.w[0];	// the result is positive
    3388      } else if (exp == 0) {
    3389        // 1 <= q <= 20, but x < 2^64 - 1/2 so in this case C1.w[1] has to be 0
    3390        // res = C (exact)
    3391        res = C1.w[0];
    3392      } else {
    3393        // if (exp > 0) => 1 <= exp <= 19, 1 <= q < 19, 2 <= q + exp <= 20
    3394        // res = C * 10^exp (exact) - must fit in 64 bits
    3395        res = C1.w[0] * ten2k64[exp];
    3396      }
    3397    }
    3398  }
    3399  
    3400  BID_RETURN (res);
    3401  }