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