(root)/
gcc-13.2.0/
libgcc/
config/
libbid/
bid128_round_integral.c
       1  /* Copyright (C) 2007-2023 Free Software Foundation, Inc.
       2  
       3  This file is part of GCC.
       4  
       5  GCC is free software; you can redistribute it and/or modify it under
       6  the terms of the GNU General Public License as published by the Free
       7  Software Foundation; either version 3, or (at your option) any later
       8  version.
       9  
      10  GCC is distributed in the hope that it will be useful, but WITHOUT ANY
      11  WARRANTY; without even the implied warranty of MERCHANTABILITY or
      12  FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
      13  for more details.
      14  
      15  Under Section 7 of GPL version 3, you are granted additional
      16  permissions described in the GCC Runtime Library Exception, version
      17  3.1, as published by the Free Software Foundation.
      18  
      19  You should have received a copy of the GNU General Public License and
      20  a copy of the GCC Runtime Library Exception along with this program;
      21  see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
      22  <http://www.gnu.org/licenses/>.  */
      23  
      24  #define BID_128RES
      25  
      26  #include "bid_internal.h"
      27  
      28  /*****************************************************************************
      29   *  BID128_round_integral_exact
      30   ****************************************************************************/
      31  
      32  BID128_FUNCTION_ARG1 (bid128_round_integral_exact, x)
      33  
      34       UINT128 res = { {0xbaddbaddbaddbaddull, 0xbaddbaddbaddbaddull}
      35       };
      36  UINT64 x_sign;
      37  UINT64 x_exp;
      38  int exp;			// unbiased exponent
      39    // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
      40  UINT64 tmp64;
      41  BID_UI64DOUBLE tmp1;
      42  unsigned int x_nr_bits;
      43  int q, ind, shift;
      44  UINT128 C1;
      45  UINT256 fstar;
      46  UINT256 P256;
      47  
      48    // check for NaN or Infinity
      49  if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
      50    // x is special
      51    if ((x.w[1] & MASK_NAN) == MASK_NAN) {	// x is NAN
      52      // if x = NaN, then res = Q (x)
      53      // check first for non-canonical NaN payload
      54      if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
      55  	(((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
      56  	 (x.w[0] > 0x38c15b09ffffffffull))) {
      57        x.w[1] = x.w[1] & 0xffffc00000000000ull;
      58        x.w[0] = 0x0ull;
      59      }
      60      if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {	// x is SNAN
      61        // set invalid flag
      62        *pfpsf |= INVALID_EXCEPTION;
      63        // return quiet (x)
      64        res.w[1] = x.w[1] & 0xfc003fffffffffffull;	// clear out also G[6]-G[16]
      65        res.w[0] = x.w[0];
      66      } else {	// x is QNaN
      67        // return x
      68        res.w[1] = x.w[1] & 0xfc003fffffffffffull;	// clear out G[6]-G[16]
      69        res.w[0] = x.w[0];
      70      }
      71      BID_RETURN (res)
      72    } else {	// x is not a NaN, so it must be infinity
      73      if ((x.w[1] & MASK_SIGN) == 0x0ull) {	// x is +inf
      74        // return +inf
      75        res.w[1] = 0x7800000000000000ull;
      76        res.w[0] = 0x0000000000000000ull;
      77      } else {	// x is -inf 
      78        // return -inf
      79        res.w[1] = 0xf800000000000000ull;
      80        res.w[0] = 0x0000000000000000ull;
      81      }
      82      BID_RETURN (res);
      83    }
      84  }
      85    // unpack x
      86  x_sign = x.w[1] & MASK_SIGN;	// 0 for positive, MASK_SIGN for negative
      87  C1.w[1] = x.w[1] & MASK_COEFF;
      88  C1.w[0] = x.w[0];
      89  
      90    // check for non-canonical values (treated as zero)
      91  if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {	// G0_G1=11
      92    // non-canonical
      93    x_exp = (x.w[1] << 2) & MASK_EXP;	// biased and shifted left 49 bits
      94    C1.w[1] = 0;	// significand high
      95    C1.w[0] = 0;	// significand low
      96  } else {	// G0_G1 != 11
      97    x_exp = x.w[1] & MASK_EXP;	// biased and shifted left 49 bits
      98    if (C1.w[1] > 0x0001ed09bead87c0ull ||
      99        (C1.w[1] == 0x0001ed09bead87c0ull
     100         && C1.w[0] > 0x378d8e63ffffffffull)) {
     101      // x is non-canonical if coefficient is larger than 10^34 -1
     102      C1.w[1] = 0;
     103      C1.w[0] = 0;
     104    } else {	// canonical
     105      ;
     106    }
     107  }
     108  
     109    // test for input equal to zero
     110  if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
     111    // x is 0
     112    // return 0 preserving the sign bit and the preferred exponent
     113    // of MAX(Q(x), 0)
     114    if (x_exp <= (0x1820ull << 49)) {
     115      res.w[1] = (x.w[1] & 0x8000000000000000ull) | 0x3040000000000000ull;
     116    } else {
     117      res.w[1] = x_sign | x_exp;
     118    }
     119    res.w[0] = 0x0000000000000000ull;
     120    BID_RETURN (res);
     121  }
     122    // x is not special and is not zero
     123  
     124  switch (rnd_mode) {
     125  case ROUNDING_TO_NEAREST:
     126  case ROUNDING_TIES_AWAY:
     127    // if (exp <= -(p+1)) return 0.0
     128    if (x_exp <= 0x2ffa000000000000ull) {	// 0x2ffa000000000000ull == -35
     129      res.w[1] = x_sign | 0x3040000000000000ull;
     130      res.w[0] = 0x0000000000000000ull;
     131      *pfpsf |= INEXACT_EXCEPTION;
     132      BID_RETURN (res);
     133    }
     134    break;
     135  case ROUNDING_DOWN:
     136    // if (exp <= -p) return -1.0 or +0.0
     137    if (x_exp <= 0x2ffc000000000000ull) {	// 0x2ffa000000000000ull == -34
     138      if (x_sign) {
     139        // if negative, return negative 1, because we know coefficient
     140        // is non-zero (would have been caught above)
     141        res.w[1] = 0xb040000000000000ull;
     142        res.w[0] = 0x0000000000000001ull;
     143      } else {
     144        // if positive, return positive 0, because we know coefficient is
     145        // non-zero (would have been caught above)
     146        res.w[1] = 0x3040000000000000ull;
     147        res.w[0] = 0x0000000000000000ull;
     148      }
     149      *pfpsf |= INEXACT_EXCEPTION;
     150      BID_RETURN (res);
     151    }
     152    break;
     153  case ROUNDING_UP:
     154    // if (exp <= -p) return -0.0 or +1.0
     155    if (x_exp <= 0x2ffc000000000000ull) {	// 0x2ffc000000000000ull == -34
     156      if (x_sign) {
     157        // if negative, return negative 0, because we know the coefficient
     158        // is non-zero (would have been caught above)
     159        res.w[1] = 0xb040000000000000ull;
     160        res.w[0] = 0x0000000000000000ull;
     161      } else {
     162        // if positive, return positive 1, because we know coefficient is
     163        // non-zero (would have been caught above)
     164        res.w[1] = 0x3040000000000000ull;
     165        res.w[0] = 0x0000000000000001ull;
     166      }
     167      *pfpsf |= INEXACT_EXCEPTION;
     168      BID_RETURN (res);
     169    }
     170    break;
     171  case ROUNDING_TO_ZERO:
     172    // if (exp <= -p) return -0.0 or +0.0
     173    if (x_exp <= 0x2ffc000000000000ull) {	// 0x2ffc000000000000ull == -34
     174      res.w[1] = x_sign | 0x3040000000000000ull;
     175      res.w[0] = 0x0000000000000000ull;
     176      *pfpsf |= INEXACT_EXCEPTION;
     177      BID_RETURN (res);
     178    }
     179    break;
     180  }
     181  
     182    // q = nr. of decimal digits in x
     183    //  determine first the nr. of bits in x
     184  if (C1.w[1] == 0) {
     185    if (C1.w[0] >= 0x0020000000000000ull) {	// x >= 2^53
     186      // split the 64-bit value in two 32-bit halves to avoid rounding errors
     187      if (C1.w[0] >= 0x0000000100000000ull) {	// x >= 2^32
     188        tmp1.d = (double) (C1.w[0] >> 32);	// exact conversion
     189        x_nr_bits =
     190  	33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     191      } else {	// x < 2^32
     192        tmp1.d = (double) (C1.w[0]);	// exact conversion
     193        x_nr_bits =
     194  	1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     195      }
     196    } else {	// if x < 2^53
     197      tmp1.d = (double) C1.w[0];	// exact conversion
     198      x_nr_bits =
     199        1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     200    }
     201  } else {	// C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
     202    tmp1.d = (double) C1.w[1];	// exact conversion
     203    x_nr_bits =
     204      65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     205  }
     206  
     207  q = nr_digits[x_nr_bits - 1].digits;
     208  if (q == 0) {
     209    q = nr_digits[x_nr_bits - 1].digits1;
     210    if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi ||
     211        (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi &&
     212         C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
     213      q++;
     214  }
     215  exp = (x_exp >> 49) - 6176;
     216  if (exp >= 0) {	// -exp <= 0
     217    // the argument is an integer already
     218    res.w[1] = x.w[1];
     219    res.w[0] = x.w[0];
     220    BID_RETURN (res);
     221  }
     222    // exp < 0
     223  switch (rnd_mode) {
     224  case ROUNDING_TO_NEAREST:
     225    if ((q + exp) >= 0) {	// exp < 0 and 1 <= -exp <= q
     226      // need to shift right -exp digits from the coefficient; exp will be 0
     227      ind = -exp;	// 1 <= ind <= 34; ind is a synonym for 'x'
     228      // chop off ind digits from the lower part of C1 
     229      // C1 = C1 + 1/2 * 10^x where the result C1 fits in 127 bits
     230      tmp64 = C1.w[0];
     231      if (ind <= 19) {
     232        C1.w[0] = C1.w[0] + midpoint64[ind - 1];
     233      } else {
     234        C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
     235        C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
     236      }
     237      if (C1.w[0] < tmp64)
     238        C1.w[1]++;
     239      // calculate C* and f*
     240      // C* is actually floor(C*) in this case
     241      // C* and f* need shifting and masking, as shown by
     242      // shiftright128[] and maskhigh128[]
     243      // 1 <= x <= 34
     244      // kx = 10^(-x) = ten2mk128[ind - 1]
     245      // C* = (C1 + 1/2 * 10^x) * 10^(-x)
     246      // the approximation of 10^(-x) was rounded up to 118 bits
     247      __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
     248      // determine the value of res and fstar
     249  
     250      // determine inexactness of the rounding of C*
     251      // if (0 < f* - 1/2 < 10^(-x)) then
     252      //   the result is exact
     253      // else // if (f* - 1/2 > T*) then
     254      //   the result is inexact
     255      // Note: we are going to use ten2mk128[] instead of ten2mk128trunc[]
     256  
     257      if (ind - 1 <= 2) {	// 0 <= ind - 1 <= 2 => shift = 0
     258        // redundant shift = shiftright128[ind - 1]; // shift = 0
     259        res.w[1] = P256.w[3];
     260        res.w[0] = P256.w[2];
     261        // redundant fstar.w[3] = 0;
     262        // redundant fstar.w[2] = 0;
     263        fstar.w[1] = P256.w[1];
     264        fstar.w[0] = P256.w[0];
     265        // fraction f* < 10^(-x) <=> midpoint
     266        // f* is in the right position to be compared with
     267        // 10^(-x) from ten2mk128[]
     268        // if 0 < fstar < 10^(-x), subtract 1 if odd (for rounding to even)
     269        if ((res.w[0] & 0x0000000000000001ull) &&	// is result odd?
     270  	  ((fstar.w[1] < (ten2mk128[ind - 1].w[1]))
     271  	   || ((fstar.w[1] == ten2mk128[ind - 1].w[1])
     272  	       && (fstar.w[0] < ten2mk128[ind - 1].w[0])))) {
     273  	// subract 1 to make even
     274  	if (res.w[0]-- == 0) {
     275  	  res.w[1]--;
     276  	}
     277        }
     278        if (fstar.w[1] > 0x8000000000000000ull ||
     279  	  (fstar.w[1] == 0x8000000000000000ull
     280  	   && fstar.w[0] > 0x0ull)) {
     281  	// f* > 1/2 and the result may be exact
     282  	tmp64 = fstar.w[1] - 0x8000000000000000ull;	// f* - 1/2
     283  	if (tmp64 > ten2mk128[ind - 1].w[1] ||
     284  	    (tmp64 == ten2mk128[ind - 1].w[1] &&
     285  	     fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
     286  	  // set the inexact flag
     287  	  *pfpsf |= INEXACT_EXCEPTION;
     288  	}	// else the result is exact 
     289        } else {	// the result is inexact; f2* <= 1/2  
     290  	// set the inexact flag 
     291  	*pfpsf |= INEXACT_EXCEPTION;
     292        }
     293      } else if (ind - 1 <= 21) {	// 3 <= ind - 1 <= 21 => 3 <= shift <= 63
     294        shift = shiftright128[ind - 1];	// 3 <= shift <= 63
     295        res.w[1] = (P256.w[3] >> shift);
     296        res.w[0] = (P256.w[3] << (64 - shift)) | (P256.w[2] >> shift);
     297        // redundant fstar.w[3] = 0;
     298        fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
     299        fstar.w[1] = P256.w[1];
     300        fstar.w[0] = P256.w[0];
     301        // fraction f* < 10^(-x) <=> midpoint
     302        // f* is in the right position to be compared with
     303        // 10^(-x) from ten2mk128[]
     304        if ((res.w[0] & 0x0000000000000001ull) &&	// is result odd?
     305  	  fstar.w[2] == 0 && (fstar.w[1] < ten2mk128[ind - 1].w[1] ||
     306  			      (fstar.w[1] == ten2mk128[ind - 1].w[1] &&
     307  			       fstar.w[0] < ten2mk128[ind - 1].w[0]))) {
     308  	// subract 1 to make even
     309  	if (res.w[0]-- == 0) {
     310  	  res.w[1]--;
     311  	}
     312        }
     313        if (fstar.w[2] > onehalf128[ind - 1] ||
     314  	  (fstar.w[2] == onehalf128[ind - 1]
     315  	   && (fstar.w[1] || fstar.w[0]))) {
     316  	// f2* > 1/2 and the result may be exact
     317  	// Calculate f2* - 1/2
     318  	tmp64 = fstar.w[2] - onehalf128[ind - 1];
     319  	if (tmp64 || fstar.w[1] > ten2mk128[ind - 1].w[1] ||
     320  	    (fstar.w[1] == ten2mk128[ind - 1].w[1] &&
     321  	     fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
     322  	  // set the inexact flag
     323  	  *pfpsf |= INEXACT_EXCEPTION;
     324  	}	// else the result is exact
     325        } else {	// the result is inexact; f2* <= 1/2
     326  	// set the inexact flag
     327  	*pfpsf |= INEXACT_EXCEPTION;
     328        }
     329      } else {	// 22 <= ind - 1 <= 33
     330        shift = shiftright128[ind - 1] - 64;	// 2 <= shift <= 38
     331        res.w[1] = 0;
     332        res.w[0] = P256.w[3] >> shift;
     333        fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
     334        fstar.w[2] = P256.w[2];
     335        fstar.w[1] = P256.w[1];
     336        fstar.w[0] = P256.w[0];
     337        // fraction f* < 10^(-x) <=> midpoint
     338        // f* is in the right position to be compared with
     339        // 10^(-x) from ten2mk128[]
     340        if ((res.w[0] & 0x0000000000000001ull) &&	// is result odd?
     341  	  fstar.w[3] == 0 && fstar.w[2] == 0 &&
     342  	  (fstar.w[1] < ten2mk128[ind - 1].w[1] ||
     343  	   (fstar.w[1] == ten2mk128[ind - 1].w[1] &&
     344  	    fstar.w[0] < ten2mk128[ind - 1].w[0]))) {
     345  	// subract 1 to make even
     346  	if (res.w[0]-- == 0) {
     347  	  res.w[1]--;
     348  	}
     349        }
     350        if (fstar.w[3] > onehalf128[ind - 1] ||
     351  	  (fstar.w[3] == onehalf128[ind - 1] &&
     352  	   (fstar.w[2] || fstar.w[1] || fstar.w[0]))) {
     353  	// f2* > 1/2 and the result may be exact
     354  	// Calculate f2* - 1/2
     355  	tmp64 = fstar.w[3] - onehalf128[ind - 1];
     356  	if (tmp64 || fstar.w[2] || fstar.w[1] > ten2mk128[ind - 1].w[1]
     357  	    || (fstar.w[1] == ten2mk128[ind - 1].w[1]
     358  		&& fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
     359  	  // set the inexact flag
     360  	  *pfpsf |= INEXACT_EXCEPTION;
     361  	}	// else the result is exact
     362        } else {	// the result is inexact; f2* <= 1/2
     363  	// set the inexact flag
     364  	*pfpsf |= INEXACT_EXCEPTION;
     365        }
     366      }
     367      res.w[1] = x_sign | 0x3040000000000000ull | res.w[1];
     368      BID_RETURN (res);
     369    } else {	// if ((q + exp) < 0) <=> q < -exp
     370      // the result is +0 or -0
     371      res.w[1] = x_sign | 0x3040000000000000ull;
     372      res.w[0] = 0x0000000000000000ull;
     373      *pfpsf |= INEXACT_EXCEPTION;
     374      BID_RETURN (res);
     375    }
     376    break;
     377  case ROUNDING_TIES_AWAY:
     378    if ((q + exp) >= 0) {	// exp < 0 and 1 <= -exp <= q
     379      // need to shift right -exp digits from the coefficient; exp will be 0
     380      ind = -exp;	// 1 <= ind <= 34; ind is a synonym for 'x'
     381      // chop off ind digits from the lower part of C1 
     382      // C1 = C1 + 1/2 * 10^x where the result C1 fits in 127 bits
     383      tmp64 = C1.w[0];
     384      if (ind <= 19) {
     385        C1.w[0] = C1.w[0] + midpoint64[ind - 1];
     386      } else {
     387        C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
     388        C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
     389      }
     390      if (C1.w[0] < tmp64)
     391        C1.w[1]++;
     392      // calculate C* and f*
     393      // C* is actually floor(C*) in this case
     394      // C* and f* need shifting and masking, as shown by
     395      // shiftright128[] and maskhigh128[]
     396      // 1 <= x <= 34
     397      // kx = 10^(-x) = ten2mk128[ind - 1]
     398      // C* = (C1 + 1/2 * 10^x) * 10^(-x)
     399      // the approximation of 10^(-x) was rounded up to 118 bits
     400      __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
     401      // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
     402      // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
     403      // if (0 < f* < 10^(-x)) then the result is a midpoint
     404      //   if floor(C*) is even then C* = floor(C*) - logical right
     405      //       shift; C* has p decimal digits, correct by Prop. 1)
     406      //   else if floor(C*) is odd C* = floor(C*)-1 (logical right
     407      //       shift; C* has p decimal digits, correct by Pr. 1)
     408      // else
     409      //   C* = floor(C*) (logical right shift; C has p decimal digits,
     410      //       correct by Property 1)
     411      // n = C* * 10^(e+x)
     412  
     413      // determine also the inexactness of the rounding of C*
     414      // if (0 < f* - 1/2 < 10^(-x)) then
     415      //   the result is exact
     416      // else // if (f* - 1/2 > T*) then
     417      //   the result is inexact
     418      // Note: we are going to use ten2mk128[] instead of ten2mk128trunc[]
     419      // shift right C* by Ex-128 = shiftright128[ind]
     420      if (ind - 1 <= 2) {	// 0 <= ind - 1 <= 2 => shift = 0
     421        // redundant shift = shiftright128[ind - 1]; // shift = 0
     422        res.w[1] = P256.w[3];
     423        res.w[0] = P256.w[2];
     424        // redundant fstar.w[3] = 0;
     425        // redundant fstar.w[2] = 0;
     426        fstar.w[1] = P256.w[1];
     427        fstar.w[0] = P256.w[0];
     428        if (fstar.w[1] > 0x8000000000000000ull ||
     429  	  (fstar.w[1] == 0x8000000000000000ull
     430  	   && fstar.w[0] > 0x0ull)) {
     431  	// f* > 1/2 and the result may be exact
     432  	tmp64 = fstar.w[1] - 0x8000000000000000ull;	// f* - 1/2
     433  	if ((tmp64 > ten2mk128[ind - 1].w[1] ||
     434  	     (tmp64 == ten2mk128[ind - 1].w[1] &&
     435  	      fstar.w[0] >= ten2mk128[ind - 1].w[0]))) {
     436  	  // set the inexact flag
     437  	  *pfpsf |= INEXACT_EXCEPTION;
     438  	}	// else the result is exact
     439        } else {	// the result is inexact; f2* <= 1/2
     440  	// set the inexact flag
     441  	*pfpsf |= INEXACT_EXCEPTION;
     442        }
     443      } else if (ind - 1 <= 21) {	// 3 <= ind - 1 <= 21 => 3 <= shift <= 63
     444        shift = shiftright128[ind - 1];	// 3 <= shift <= 63
     445        res.w[1] = (P256.w[3] >> shift);
     446        res.w[0] = (P256.w[3] << (64 - shift)) | (P256.w[2] >> shift);
     447        // redundant fstar.w[3] = 0;
     448        fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
     449        fstar.w[1] = P256.w[1];
     450        fstar.w[0] = P256.w[0];
     451        if (fstar.w[2] > onehalf128[ind - 1] ||
     452  	  (fstar.w[2] == onehalf128[ind - 1]
     453  	   && (fstar.w[1] || fstar.w[0]))) {
     454  	// f2* > 1/2 and the result may be exact
     455  	// Calculate f2* - 1/2
     456  	tmp64 = fstar.w[2] - onehalf128[ind - 1];
     457  	if (tmp64 || fstar.w[1] > ten2mk128[ind - 1].w[1] ||
     458  	    (fstar.w[1] == ten2mk128[ind - 1].w[1] &&
     459  	     fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
     460  	  // set the inexact flag
     461  	  *pfpsf |= INEXACT_EXCEPTION;
     462  	}	// else the result is exact
     463        } else {	// the result is inexact; f2* <= 1/2
     464  	// set the inexact flag
     465  	*pfpsf |= INEXACT_EXCEPTION;
     466        }
     467      } else {	// 22 <= ind - 1 <= 33
     468        shift = shiftright128[ind - 1] - 64;	// 2 <= shift <= 38
     469        res.w[1] = 0;
     470        res.w[0] = P256.w[3] >> shift;
     471        fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
     472        fstar.w[2] = P256.w[2];
     473        fstar.w[1] = P256.w[1];
     474        fstar.w[0] = P256.w[0];
     475        if (fstar.w[3] > onehalf128[ind - 1] ||
     476  	  (fstar.w[3] == onehalf128[ind - 1] &&
     477  	   (fstar.w[2] || fstar.w[1] || fstar.w[0]))) {
     478  	// f2* > 1/2 and the result may be exact
     479  	// Calculate f2* - 1/2
     480  	tmp64 = fstar.w[3] - onehalf128[ind - 1];
     481  	if (tmp64 || fstar.w[2] || fstar.w[1] > ten2mk128[ind - 1].w[1]
     482  	    || (fstar.w[1] == ten2mk128[ind - 1].w[1]
     483  		&& fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
     484  	  // set the inexact flag
     485  	  *pfpsf |= INEXACT_EXCEPTION;
     486  	}	// else the result is exact
     487        } else {	// the result is inexact; f2* <= 1/2
     488  	// set the inexact flag
     489  	*pfpsf |= INEXACT_EXCEPTION;
     490        }
     491      }
     492      // if the result was a midpoint, it was already rounded away from zero
     493      res.w[1] |= x_sign | 0x3040000000000000ull;
     494      BID_RETURN (res);
     495    } else {	// if ((q + exp) < 0) <=> q < -exp
     496      // the result is +0 or -0
     497      res.w[1] = x_sign | 0x3040000000000000ull;
     498      res.w[0] = 0x0000000000000000ull;
     499      *pfpsf |= INEXACT_EXCEPTION;
     500      BID_RETURN (res);
     501    }
     502    break;
     503  case ROUNDING_DOWN:
     504    if ((q + exp) > 0) {	// exp < 0 and 1 <= -exp < q
     505      // need to shift right -exp digits from the coefficient; exp will be 0
     506      ind = -exp;	// 1 <= ind <= 34; ind is a synonym for 'x' 
     507      // (number of digits to be chopped off)
     508      // chop off ind digits from the lower part of C1 
     509      // FOR ROUND_TO_NEAREST, WE ADD 1/2 ULP(y) then truncate
     510      // FOR ROUND_TO_ZERO, WE DON'T NEED TO ADD 1/2 ULP
     511      // FOR ROUND_TO_POSITIVE_INFINITY, WE TRUNCATE, THEN ADD 1 IF POSITIVE
     512      // FOR ROUND_TO_NEGATIVE_INFINITY, WE TRUNCATE, THEN ADD 1 IF NEGATIVE
     513      // tmp64 = C1.w[0];
     514      // if (ind <= 19) {
     515      //   C1.w[0] = C1.w[0] + midpoint64[ind - 1];
     516      // } else {
     517      //   C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
     518      //   C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
     519      // }
     520      // if (C1.w[0] < tmp64) C1.w[1]++;
     521      // if carry-out from C1.w[0], increment C1.w[1]
     522      // calculate C* and f*
     523      // C* is actually floor(C*) in this case
     524      // C* and f* need shifting and masking, as shown by
     525      // shiftright128[] and maskhigh128[]
     526      // 1 <= x <= 34
     527      // kx = 10^(-x) = ten2mk128[ind - 1]
     528      // C* = (C1 + 1/2 * 10^x) * 10^(-x)
     529      // the approximation of 10^(-x) was rounded up to 118 bits
     530      __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
     531      if (ind - 1 <= 2) {	// 0 <= ind - 1 <= 2 => shift = 0
     532        res.w[1] = P256.w[3];
     533        res.w[0] = P256.w[2];
     534        // redundant fstar.w[3] = 0;
     535        // redundant fstar.w[2] = 0;
     536        // redundant fstar.w[1] = P256.w[1];
     537        // redundant fstar.w[0] = P256.w[0];
     538        // fraction f* > 10^(-x) <=> inexact
     539        // f* is in the right position to be compared with
     540        // 10^(-x) from ten2mk128[]
     541        if ((P256.w[1] > ten2mk128[ind - 1].w[1])
     542  	  || (P256.w[1] == ten2mk128[ind - 1].w[1]
     543  	      && (P256.w[0] >= ten2mk128[ind - 1].w[0]))) {
     544  	*pfpsf |= INEXACT_EXCEPTION;
     545  	// if positive, the truncated value is already the correct result
     546  	if (x_sign) {	// if negative
     547  	  if (++res.w[0] == 0) {
     548  	    res.w[1]++;
     549  	  }
     550  	}
     551        }
     552      } else if (ind - 1 <= 21) {	// 3 <= ind - 1 <= 21 => 3 <= shift <= 63
     553        shift = shiftright128[ind - 1];	// 0 <= shift <= 102
     554        res.w[1] = (P256.w[3] >> shift);
     555        res.w[0] = (P256.w[3] << (64 - shift)) | (P256.w[2] >> shift);
     556        // redundant fstar.w[3] = 0;
     557        fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
     558        fstar.w[1] = P256.w[1];
     559        fstar.w[0] = P256.w[0];
     560        // fraction f* > 10^(-x) <=> inexact
     561        // f* is in the right position to be compared with
     562        // 10^(-x) from ten2mk128[]
     563        if (fstar.w[2] || fstar.w[1] > ten2mk128[ind - 1].w[1] ||
     564  	  (fstar.w[1] == ten2mk128[ind - 1].w[1] &&
     565  	   fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
     566  	*pfpsf |= INEXACT_EXCEPTION;
     567  	// if positive, the truncated value is already the correct result
     568  	if (x_sign) {	// if negative
     569  	  if (++res.w[0] == 0) {
     570  	    res.w[1]++;
     571  	  }
     572  	}
     573        }
     574      } else {	// 22 <= ind - 1 <= 33
     575        shift = shiftright128[ind - 1] - 64;	// 2 <= shift <= 38
     576        res.w[1] = 0;
     577        res.w[0] = P256.w[3] >> shift;
     578        fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
     579        fstar.w[2] = P256.w[2];
     580        fstar.w[1] = P256.w[1];
     581        fstar.w[0] = P256.w[0];
     582        // fraction f* > 10^(-x) <=> inexact
     583        // f* is in the right position to be compared with
     584        // 10^(-x) from ten2mk128[]
     585        if (fstar.w[3] || fstar.w[2]
     586  	  || fstar.w[1] > ten2mk128[ind - 1].w[1]
     587  	  || (fstar.w[1] == ten2mk128[ind - 1].w[1]
     588  	      && fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
     589  	*pfpsf |= INEXACT_EXCEPTION;
     590  	// if positive, the truncated value is already the correct result
     591  	if (x_sign) {	// if negative
     592  	  if (++res.w[0] == 0) {
     593  	    res.w[1]++;
     594  	  }
     595  	}
     596        }
     597      }
     598      res.w[1] = x_sign | 0x3040000000000000ull | res.w[1];
     599      BID_RETURN (res);
     600    } else {	// if exp < 0 and q + exp <= 0
     601      if (x_sign) {	// negative rounds down to -1.0
     602        res.w[1] = 0xb040000000000000ull;
     603        res.w[0] = 0x0000000000000001ull;
     604      } else {	// positive rpunds down to +0.0
     605        res.w[1] = 0x3040000000000000ull;
     606        res.w[0] = 0x0000000000000000ull;
     607      }
     608      *pfpsf |= INEXACT_EXCEPTION;
     609      BID_RETURN (res);
     610    }
     611    break;
     612  case ROUNDING_UP:
     613    if ((q + exp) > 0) {	// exp < 0 and 1 <= -exp < q
     614      // need to shift right -exp digits from the coefficient; exp will be 0
     615      ind = -exp;	// 1 <= ind <= 34; ind is a synonym for 'x' 
     616      // (number of digits to be chopped off)
     617      // chop off ind digits from the lower part of C1 
     618      // FOR ROUND_TO_NEAREST, WE ADD 1/2 ULP(y) then truncate
     619      // FOR ROUND_TO_ZERO, WE DON'T NEED TO ADD 1/2 ULP
     620      // FOR ROUND_TO_POSITIVE_INFINITY, WE TRUNCATE, THEN ADD 1 IF POSITIVE
     621      // FOR ROUND_TO_NEGATIVE_INFINITY, WE TRUNCATE, THEN ADD 1 IF NEGATIVE
     622      // tmp64 = C1.w[0];
     623      // if (ind <= 19) {
     624      //   C1.w[0] = C1.w[0] + midpoint64[ind - 1];
     625      // } else {
     626      //   C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
     627      //   C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
     628      // }
     629      // if (C1.w[0] < tmp64) C1.w[1]++;  
     630      // if carry-out from C1.w[0], increment C1.w[1]
     631      // calculate C* and f*
     632      // C* is actually floor(C*) in this case
     633      // C* and f* need shifting and masking, as shown by
     634      // shiftright128[] and maskhigh128[]
     635      // 1 <= x <= 34
     636      // kx = 10^(-x) = ten2mk128[ind - 1]
     637      // C* = C1 * 10^(-x)
     638      // the approximation of 10^(-x) was rounded up to 118 bits
     639      __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
     640      if (ind - 1 <= 2) {	// 0 <= ind - 1 <= 2 => shift = 0
     641        res.w[1] = P256.w[3];
     642        res.w[0] = P256.w[2];
     643        // redundant fstar.w[3] = 0;
     644        // redundant fstar.w[2] = 0;
     645        // redundant fstar.w[1] = P256.w[1]; 
     646        // redundant fstar.w[0] = P256.w[0];
     647        // fraction f* > 10^(-x) <=> inexact
     648        // f* is in the right position to be compared with 
     649        // 10^(-x) from ten2mk128[]
     650        if ((P256.w[1] > ten2mk128[ind - 1].w[1])
     651  	  || (P256.w[1] == ten2mk128[ind - 1].w[1]
     652  	      && (P256.w[0] >= ten2mk128[ind - 1].w[0]))) {
     653  	*pfpsf |= INEXACT_EXCEPTION;
     654  	// if negative, the truncated value is already the correct result
     655  	if (!x_sign) {	// if positive
     656  	  if (++res.w[0] == 0) {
     657  	    res.w[1]++;
     658  	  }
     659  	}
     660        }
     661      } else if (ind - 1 <= 21) {	// 3 <= ind - 1 <= 21 => 3 <= shift <= 63
     662        shift = shiftright128[ind - 1];	// 3 <= shift <= 63
     663        res.w[1] = (P256.w[3] >> shift);
     664        res.w[0] = (P256.w[3] << (64 - shift)) | (P256.w[2] >> shift);
     665        // redundant fstar.w[3] = 0;
     666        fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
     667        fstar.w[1] = P256.w[1];
     668        fstar.w[0] = P256.w[0];
     669        // fraction f* > 10^(-x) <=> inexact
     670        // f* is in the right position to be compared with 
     671        // 10^(-x) from ten2mk128[]
     672        if (fstar.w[2] || fstar.w[1] > ten2mk128[ind - 1].w[1] ||
     673  	  (fstar.w[1] == ten2mk128[ind - 1].w[1] &&
     674  	   fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
     675  	*pfpsf |= INEXACT_EXCEPTION;
     676  	// if negative, the truncated value is already the correct result
     677  	if (!x_sign) {	// if positive
     678  	  if (++res.w[0] == 0) {
     679  	    res.w[1]++;
     680  	  }
     681  	}
     682        }
     683      } else {	// 22 <= ind - 1 <= 33
     684        shift = shiftright128[ind - 1] - 64;	// 2 <= shift <= 38
     685        res.w[1] = 0;
     686        res.w[0] = P256.w[3] >> shift;
     687        fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
     688        fstar.w[2] = P256.w[2];
     689        fstar.w[1] = P256.w[1];
     690        fstar.w[0] = P256.w[0];
     691        // fraction f* > 10^(-x) <=> inexact
     692        // f* is in the right position to be compared with 
     693        // 10^(-x) from ten2mk128[]
     694        if (fstar.w[3] || fstar.w[2]
     695  	  || fstar.w[1] > ten2mk128[ind - 1].w[1]
     696  	  || (fstar.w[1] == ten2mk128[ind - 1].w[1]
     697  	      && fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
     698  	*pfpsf |= INEXACT_EXCEPTION;
     699  	// if negative, the truncated value is already the correct result
     700  	if (!x_sign) {	// if positive
     701  	  if (++res.w[0] == 0) {
     702  	    res.w[1]++;
     703  	  }
     704  	}
     705        }
     706      }
     707      res.w[1] = x_sign | 0x3040000000000000ull | res.w[1];
     708      BID_RETURN (res);
     709    } else {	// if exp < 0 and q + exp <= 0
     710      if (x_sign) {	// negative rounds up to -0.0
     711        res.w[1] = 0xb040000000000000ull;
     712        res.w[0] = 0x0000000000000000ull;
     713      } else {	// positive rpunds up to +1.0
     714        res.w[1] = 0x3040000000000000ull;
     715        res.w[0] = 0x0000000000000001ull;
     716      }
     717      *pfpsf |= INEXACT_EXCEPTION;
     718      BID_RETURN (res);
     719    }
     720    break;
     721  case ROUNDING_TO_ZERO:
     722    if ((q + exp) > 0) {	// exp < 0 and 1 <= -exp < q
     723      // need to shift right -exp digits from the coefficient; exp will be 0
     724      ind = -exp;	// 1 <= ind <= 34; ind is a synonym for 'x'
     725      // (number of digits to be chopped off)
     726      // chop off ind digits from the lower part of C1 
     727      // FOR ROUND_TO_NEAREST, WE ADD 1/2 ULP(y) then truncate
     728      // FOR ROUND_TO_ZERO, WE DON'T NEED TO ADD 1/2 ULP
     729      // FOR ROUND_TO_POSITIVE_INFINITY, WE TRUNCATE, THEN ADD 1 IF POSITIVE
     730      // FOR ROUND_TO_NEGATIVE_INFINITY, WE TRUNCATE, THEN ADD 1 IF NEGATIVE
     731      //tmp64 = C1.w[0];
     732      // if (ind <= 19) {
     733      //   C1.w[0] = C1.w[0] + midpoint64[ind - 1];
     734      // } else {
     735      //   C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
     736      //   C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
     737      // }
     738      // if (C1.w[0] < tmp64) C1.w[1]++;  
     739      // if carry-out from C1.w[0], increment C1.w[1]
     740      // calculate C* and f*
     741      // C* is actually floor(C*) in this case
     742      // C* and f* need shifting and masking, as shown by
     743      // shiftright128[] and maskhigh128[]
     744      // 1 <= x <= 34
     745      // kx = 10^(-x) = ten2mk128[ind - 1]
     746      // C* = (C1 + 1/2 * 10^x) * 10^(-x)
     747      // the approximation of 10^(-x) was rounded up to 118 bits
     748      __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
     749      if (ind - 1 <= 2) {	// 0 <= ind - 1 <= 2 => shift = 0
     750        res.w[1] = P256.w[3];
     751        res.w[0] = P256.w[2];
     752        // redundant fstar.w[3] = 0;
     753        // redundant fstar.w[2] = 0;
     754        // redundant fstar.w[1] = P256.w[1]; 
     755        // redundant fstar.w[0] = P256.w[0];
     756        // fraction f* > 10^(-x) <=> inexact
     757        // f* is in the right position to be compared with 
     758        // 10^(-x) from ten2mk128[]
     759        if ((P256.w[1] > ten2mk128[ind - 1].w[1])
     760  	  || (P256.w[1] == ten2mk128[ind - 1].w[1]
     761  	      && (P256.w[0] >= ten2mk128[ind - 1].w[0]))) {
     762  	*pfpsf |= INEXACT_EXCEPTION;
     763        }
     764      } else if (ind - 1 <= 21) {	// 3 <= ind - 1 <= 21 => 3 <= shift <= 63
     765        shift = shiftright128[ind - 1];	// 3 <= shift <= 63
     766        res.w[1] = (P256.w[3] >> shift);
     767        res.w[0] = (P256.w[3] << (64 - shift)) | (P256.w[2] >> shift);
     768        // redundant fstar.w[3] = 0;
     769        fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
     770        fstar.w[1] = P256.w[1];
     771        fstar.w[0] = P256.w[0];
     772        // fraction f* > 10^(-x) <=> inexact
     773        // f* is in the right position to be compared with 
     774        // 10^(-x) from ten2mk128[]
     775        if (fstar.w[2] || fstar.w[1] > ten2mk128[ind - 1].w[1] ||
     776  	  (fstar.w[1] == ten2mk128[ind - 1].w[1] &&
     777  	   fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
     778  	*pfpsf |= INEXACT_EXCEPTION;
     779        }
     780      } else {	// 22 <= ind - 1 <= 33
     781        shift = shiftright128[ind - 1] - 64;	// 2 <= shift <= 38
     782        res.w[1] = 0;
     783        res.w[0] = P256.w[3] >> shift;
     784        fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
     785        fstar.w[2] = P256.w[2];
     786        fstar.w[1] = P256.w[1];
     787        fstar.w[0] = P256.w[0];
     788        // fraction f* > 10^(-x) <=> inexact
     789        // f* is in the right position to be compared with 
     790        // 10^(-x) from ten2mk128[]
     791        if (fstar.w[3] || fstar.w[2]
     792  	  || fstar.w[1] > ten2mk128[ind - 1].w[1]
     793  	  || (fstar.w[1] == ten2mk128[ind - 1].w[1]
     794  	      && fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
     795  	*pfpsf |= INEXACT_EXCEPTION;
     796        }
     797      }
     798      res.w[1] = x_sign | 0x3040000000000000ull | res.w[1];
     799      BID_RETURN (res);
     800    } else {	// if exp < 0 and q + exp <= 0 the result is +0 or -0
     801      res.w[1] = x_sign | 0x3040000000000000ull;
     802      res.w[0] = 0x0000000000000000ull;
     803      *pfpsf |= INEXACT_EXCEPTION;
     804      BID_RETURN (res);
     805    }
     806    break;
     807  }
     808  
     809  BID_RETURN (res);
     810  }
     811  
     812  /*****************************************************************************
     813   *  BID128_round_integral_nearest_even
     814   ****************************************************************************/
     815  
     816  BID128_FUNCTION_ARG1_NORND (bid128_round_integral_nearest_even, x)
     817  
     818       UINT128 res;
     819       UINT64 x_sign;
     820       UINT64 x_exp;
     821       int exp;			// unbiased exponent
     822    // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo (all are UINT64)
     823       UINT64 tmp64;
     824       BID_UI64DOUBLE tmp1;
     825       unsigned int x_nr_bits;
     826       int q, ind, shift;
     827       UINT128 C1;
     828    // UINT128 res is C* at first - represents up to 34 decimal digits ~ 113 bits
     829       UINT256 fstar;
     830       UINT256 P256;
     831  
     832    // check for NaN or Infinity
     833  if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
     834      // x is special
     835  if ((x.w[1] & MASK_NAN) == MASK_NAN) {	// x is NAN
     836    // if x = NaN, then res = Q (x)
     837    // check first for non-canonical NaN payload
     838    if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
     839        (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
     840         (x.w[0] > 0x38c15b09ffffffffull))) {
     841      x.w[1] = x.w[1] & 0xffffc00000000000ull;
     842      x.w[0] = 0x0ull;
     843    }
     844    if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {	// x is SNAN
     845      // set invalid flag
     846      *pfpsf |= INVALID_EXCEPTION;
     847      // return quiet (x)
     848      res.w[1] = x.w[1] & 0xfc003fffffffffffull;	// clear out also G[6]-G[16]
     849      res.w[0] = x.w[0];
     850    } else {	// x is QNaN
     851      // return x
     852      res.w[1] = x.w[1] & 0xfc003fffffffffffull;	// clear out G[6]-G[16]
     853      res.w[0] = x.w[0];
     854    }
     855    BID_RETURN (res)
     856  } else {	// x is not a NaN, so it must be infinity
     857    if ((x.w[1] & MASK_SIGN) == 0x0ull) {	// x is +inf
     858      // return +inf
     859      res.w[1] = 0x7800000000000000ull;
     860      res.w[0] = 0x0000000000000000ull;
     861    } else {	// x is -inf 
     862      // return -inf
     863      res.w[1] = 0xf800000000000000ull;
     864      res.w[0] = 0x0000000000000000ull;
     865    }
     866    BID_RETURN (res);
     867  }
     868  }
     869    // unpack x
     870  x_sign = x.w[1] & MASK_SIGN;	// 0 for positive, MASK_SIGN for negative
     871  C1.w[1] = x.w[1] & MASK_COEFF;
     872  C1.w[0] = x.w[0];
     873  
     874    // check for non-canonical values (treated as zero)
     875  if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {	// G0_G1=11
     876    // non-canonical
     877    x_exp = (x.w[1] << 2) & MASK_EXP;	// biased and shifted left 49 bits
     878    C1.w[1] = 0;	// significand high
     879    C1.w[0] = 0;	// significand low
     880  } else {	// G0_G1 != 11
     881    x_exp = x.w[1] & MASK_EXP;	// biased and shifted left 49 bits
     882    if (C1.w[1] > 0x0001ed09bead87c0ull ||
     883        (C1.w[1] == 0x0001ed09bead87c0ull
     884         && C1.w[0] > 0x378d8e63ffffffffull)) {
     885      // x is non-canonical if coefficient is larger than 10^34 -1
     886      C1.w[1] = 0;
     887      C1.w[0] = 0;
     888    } else {	// canonical
     889      ;
     890    }
     891  }
     892  
     893    // test for input equal to zero
     894  if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
     895    // x is 0
     896    // return 0 preserving the sign bit and the preferred exponent
     897    // of MAX(Q(x), 0)
     898    if (x_exp <= (0x1820ull << 49)) {
     899      res.w[1] = (x.w[1] & 0x8000000000000000ull) | 0x3040000000000000ull;
     900    } else {
     901      res.w[1] = x_sign | x_exp;
     902    }
     903    res.w[0] = 0x0000000000000000ull;
     904    BID_RETURN (res);
     905  }
     906    // x is not special and is not zero
     907  
     908    // if (exp <= -(p+1)) return 0
     909  if (x_exp <= 0x2ffa000000000000ull) {	// 0x2ffa000000000000ull == -35
     910    res.w[1] = x_sign | 0x3040000000000000ull;
     911    res.w[0] = 0x0000000000000000ull;
     912    BID_RETURN (res);
     913  }
     914    // q = nr. of decimal digits in x
     915    //  determine first the nr. of bits in x
     916  if (C1.w[1] == 0) {
     917    if (C1.w[0] >= 0x0020000000000000ull) {	// x >= 2^53
     918      // split the 64-bit value in two 32-bit halves to avoid rounding errors
     919      if (C1.w[0] >= 0x0000000100000000ull) {	// x >= 2^32
     920        tmp1.d = (double) (C1.w[0] >> 32);	// exact conversion
     921        x_nr_bits =
     922  	33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     923      } else {	// x < 2^32
     924        tmp1.d = (double) (C1.w[0]);	// exact conversion
     925        x_nr_bits =
     926  	1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     927      }
     928    } else {	// if x < 2^53
     929      tmp1.d = (double) C1.w[0];	// exact conversion
     930      x_nr_bits =
     931        1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     932    }
     933  } else {	// C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
     934    tmp1.d = (double) C1.w[1];	// exact conversion
     935    x_nr_bits =
     936      65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
     937  }
     938  
     939  q = nr_digits[x_nr_bits - 1].digits;
     940  if (q == 0) {
     941    q = nr_digits[x_nr_bits - 1].digits1;
     942    if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi
     943        || (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi &&
     944  	  C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
     945      q++;
     946  }
     947  exp = (x_exp >> 49) - 6176;
     948  if (exp >= 0) {	// -exp <= 0
     949    // the argument is an integer already
     950    res.w[1] = x.w[1];
     951    res.w[0] = x.w[0];
     952    BID_RETURN (res);
     953  } else if ((q + exp) >= 0) {	// exp < 0 and 1 <= -exp <= q
     954    // need to shift right -exp digits from the coefficient; the exp will be 0
     955    ind = -exp;	// 1 <= ind <= 34; ind is a synonym for 'x'
     956    // chop off ind digits from the lower part of C1 
     957    // C1 = C1 + 1/2 * 10^x where the result C1 fits in 127 bits
     958    tmp64 = C1.w[0];
     959    if (ind <= 19) {
     960      C1.w[0] = C1.w[0] + midpoint64[ind - 1];
     961    } else {
     962      C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
     963      C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
     964    }
     965    if (C1.w[0] < tmp64)
     966      C1.w[1]++;
     967    // calculate C* and f*
     968    // C* is actually floor(C*) in this case
     969    // C* and f* need shifting and masking, as shown by
     970    // shiftright128[] and maskhigh128[]
     971    // 1 <= x <= 34
     972    // kx = 10^(-x) = ten2mk128[ind - 1]
     973    // C* = (C1 + 1/2 * 10^x) * 10^(-x)
     974    // the approximation of 10^(-x) was rounded up to 118 bits
     975    __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
     976    // determine the value of res and fstar
     977    if (ind - 1 <= 2) {	// 0 <= ind - 1 <= 2 => shift = 0
     978      // redundant shift = shiftright128[ind - 1]; // shift = 0
     979      res.w[1] = P256.w[3];
     980      res.w[0] = P256.w[2];
     981      // redundant fstar.w[3] = 0;
     982      // redundant fstar.w[2] = 0;
     983      // redundant fstar.w[1] = P256.w[1];
     984      // redundant fstar.w[0] = P256.w[0];
     985      // fraction f* < 10^(-x) <=> midpoint
     986      // f* is in the right position to be compared with
     987      // 10^(-x) from ten2mk128[]
     988      // if 0 < fstar < 10^(-x), subtract 1 if odd (for rounding to even)
     989      if ((res.w[0] & 0x0000000000000001ull) &&	// is result odd?
     990  	((P256.w[1] < (ten2mk128[ind - 1].w[1]))
     991  	 || ((P256.w[1] == ten2mk128[ind - 1].w[1])
     992  	     && (P256.w[0] < ten2mk128[ind - 1].w[0])))) {
     993        // subract 1 to make even
     994        if (res.w[0]-- == 0) {
     995  	res.w[1]--;
     996        }
     997      }
     998    } else if (ind - 1 <= 21) {	// 3 <= ind - 1 <= 21 => 3 <= shift <= 63
     999      shift = shiftright128[ind - 1];	// 3 <= shift <= 63
    1000      res.w[1] = (P256.w[3] >> shift);
    1001      res.w[0] = (P256.w[3] << (64 - shift)) | (P256.w[2] >> shift);
    1002      // redundant fstar.w[3] = 0;
    1003      fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
    1004      fstar.w[1] = P256.w[1];
    1005      fstar.w[0] = P256.w[0];
    1006      // fraction f* < 10^(-x) <=> midpoint
    1007      // f* is in the right position to be compared with
    1008      // 10^(-x) from ten2mk128[]
    1009      if ((res.w[0] & 0x0000000000000001ull) &&	// is result odd?
    1010  	fstar.w[2] == 0 && (fstar.w[1] < ten2mk128[ind - 1].w[1] ||
    1011  			    (fstar.w[1] == ten2mk128[ind - 1].w[1] &&
    1012  			     fstar.w[0] < ten2mk128[ind - 1].w[0]))) {
    1013        // subract 1 to make even
    1014        if (res.w[0]-- == 0) {
    1015  	res.w[1]--;
    1016        }
    1017      }
    1018    } else {	// 22 <= ind - 1 <= 33
    1019      shift = shiftright128[ind - 1] - 64;	// 2 <= shift <= 38
    1020      res.w[1] = 0;
    1021      res.w[0] = P256.w[3] >> shift;
    1022      fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
    1023      fstar.w[2] = P256.w[2];
    1024      fstar.w[1] = P256.w[1];
    1025      fstar.w[0] = P256.w[0];
    1026      // fraction f* < 10^(-x) <=> midpoint
    1027      // f* is in the right position to be compared with
    1028      // 10^(-x) from ten2mk128[]
    1029      if ((res.w[0] & 0x0000000000000001ull) &&	// is result odd?
    1030  	fstar.w[3] == 0 && fstar.w[2] == 0
    1031  	&& (fstar.w[1] < ten2mk128[ind - 1].w[1]
    1032  	    || (fstar.w[1] == ten2mk128[ind - 1].w[1]
    1033  		&& fstar.w[0] < ten2mk128[ind - 1].w[0]))) {
    1034        // subract 1 to make even
    1035        if (res.w[0]-- == 0) {
    1036  	res.w[1]--;
    1037        }
    1038      }
    1039    }
    1040    res.w[1] = x_sign | 0x3040000000000000ull | res.w[1];
    1041    BID_RETURN (res);
    1042  } else {	// if ((q + exp) < 0) <=> q < -exp
    1043    // the result is +0 or -0
    1044    res.w[1] = x_sign | 0x3040000000000000ull;
    1045    res.w[0] = 0x0000000000000000ull;
    1046    BID_RETURN (res);
    1047  }
    1048  }
    1049  
    1050  /*****************************************************************************
    1051   *  BID128_round_integral_negative
    1052   ****************************************************************************/
    1053  
    1054  BID128_FUNCTION_ARG1_NORND (bid128_round_integral_negative, x)
    1055  
    1056       UINT128 res;
    1057       UINT64 x_sign;
    1058       UINT64 x_exp;
    1059       int exp;			// unbiased exponent
    1060    // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo 
    1061    // (all are UINT64)
    1062       BID_UI64DOUBLE tmp1;
    1063       unsigned int x_nr_bits;
    1064       int q, ind, shift;
    1065       UINT128 C1;
    1066    // UINT128 res is C* at first - represents up to 34 decimal digits ~ 
    1067    // 113 bits
    1068       UINT256 fstar;
    1069       UINT256 P256;
    1070  
    1071    // check for NaN or Infinity
    1072  if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
    1073      // x is special
    1074  if ((x.w[1] & MASK_NAN) == MASK_NAN) {	// x is NAN
    1075    // if x = NaN, then res = Q (x)
    1076    // check first for non-canonical NaN payload
    1077    if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
    1078        (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
    1079         (x.w[0] > 0x38c15b09ffffffffull))) {
    1080      x.w[1] = x.w[1] & 0xffffc00000000000ull;
    1081      x.w[0] = 0x0ull;
    1082    }
    1083    if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {	// x is SNAN
    1084      // set invalid flag
    1085      *pfpsf |= INVALID_EXCEPTION;
    1086      // return quiet (x)
    1087      res.w[1] = x.w[1] & 0xfc003fffffffffffull;	// clear out also G[6]-G[16]
    1088      res.w[0] = x.w[0];
    1089    } else {	// x is QNaN
    1090      // return x
    1091      res.w[1] = x.w[1] & 0xfc003fffffffffffull;	// clear out G[6]-G[16]
    1092      res.w[0] = x.w[0];
    1093    }
    1094    BID_RETURN (res)
    1095  } else {	// x is not a NaN, so it must be infinity
    1096    if ((x.w[1] & MASK_SIGN) == 0x0ull) {	// x is +inf
    1097      // return +inf
    1098      res.w[1] = 0x7800000000000000ull;
    1099      res.w[0] = 0x0000000000000000ull;
    1100    } else {	// x is -inf 
    1101      // return -inf
    1102      res.w[1] = 0xf800000000000000ull;
    1103      res.w[0] = 0x0000000000000000ull;
    1104    }
    1105    BID_RETURN (res);
    1106  }
    1107  }
    1108    // unpack x
    1109  x_sign = x.w[1] & MASK_SIGN;	// 0 for positive, MASK_SIGN for negative
    1110  C1.w[1] = x.w[1] & MASK_COEFF;
    1111  C1.w[0] = x.w[0];
    1112  
    1113    // check for non-canonical values (treated as zero)
    1114  if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {	// G0_G1=11
    1115    // non-canonical
    1116    x_exp = (x.w[1] << 2) & MASK_EXP;	// biased and shifted left 49 bits
    1117    C1.w[1] = 0;	// significand high
    1118    C1.w[0] = 0;	// significand low
    1119  } else {	// G0_G1 != 11
    1120    x_exp = x.w[1] & MASK_EXP;	// biased and shifted left 49 bits
    1121    if (C1.w[1] > 0x0001ed09bead87c0ull ||
    1122        (C1.w[1] == 0x0001ed09bead87c0ull
    1123         && C1.w[0] > 0x378d8e63ffffffffull)) {
    1124      // x is non-canonical if coefficient is larger than 10^34 -1
    1125      C1.w[1] = 0;
    1126      C1.w[0] = 0;
    1127    } else {	// canonical
    1128      ;
    1129    }
    1130  }
    1131  
    1132    // test for input equal to zero
    1133  if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
    1134    // x is 0
    1135    // return 0 preserving the sign bit and the preferred exponent
    1136    // of MAX(Q(x), 0)
    1137    if (x_exp <= (0x1820ull << 49)) {
    1138      res.w[1] = (x.w[1] & 0x8000000000000000ull) | 0x3040000000000000ull;
    1139    } else {
    1140      res.w[1] = x_sign | x_exp;
    1141    }
    1142    res.w[0] = 0x0000000000000000ull;
    1143    BID_RETURN (res);
    1144  }
    1145    // x is not special and is not zero
    1146  
    1147    // if (exp <= -p) return -1.0 or +0.0
    1148  if (x_exp <= 0x2ffc000000000000ull) {	// 0x2ffc000000000000ull == -34
    1149    if (x_sign) {
    1150      // if negative, return negative 1, because we know the coefficient
    1151      // is non-zero (would have been caught above)
    1152      res.w[1] = 0xb040000000000000ull;
    1153      res.w[0] = 0x0000000000000001ull;
    1154    } else {
    1155      // if positive, return positive 0, because we know coefficient is
    1156      // non-zero (would have been caught above)
    1157      res.w[1] = 0x3040000000000000ull;
    1158      res.w[0] = 0x0000000000000000ull;
    1159    }
    1160    BID_RETURN (res);
    1161  }
    1162    // q = nr. of decimal digits in x
    1163    // determine first the nr. of bits in x
    1164  if (C1.w[1] == 0) {
    1165    if (C1.w[0] >= 0x0020000000000000ull) {	// x >= 2^53
    1166      // split the 64-bit value in two 32-bit halves to avoid rounding errors
    1167      if (C1.w[0] >= 0x0000000100000000ull) {	// x >= 2^32
    1168        tmp1.d = (double) (C1.w[0] >> 32);	// exact conversion
    1169        x_nr_bits =
    1170  	33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1171      } else {	// x < 2^32
    1172        tmp1.d = (double) (C1.w[0]);	// exact conversion
    1173        x_nr_bits =
    1174  	1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1175      }
    1176    } else {	// if x < 2^53
    1177      tmp1.d = (double) C1.w[0];	// exact conversion
    1178      x_nr_bits =
    1179        1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1180    }
    1181  } else {	// C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
    1182    tmp1.d = (double) C1.w[1];	// exact conversion
    1183    x_nr_bits =
    1184      65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1185  }
    1186  
    1187  q = nr_digits[x_nr_bits - 1].digits;
    1188  if (q == 0) {
    1189    q = nr_digits[x_nr_bits - 1].digits1;
    1190    if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi ||
    1191        (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi &&
    1192         C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
    1193      q++;
    1194  }
    1195  exp = (x_exp >> 49) - 6176;
    1196  if (exp >= 0) {	// -exp <= 0
    1197    // the argument is an integer already
    1198    res.w[1] = x.w[1];
    1199    res.w[0] = x.w[0];
    1200    BID_RETURN (res);
    1201  } else if ((q + exp) > 0) {	// exp < 0 and 1 <= -exp < q
    1202    // need to shift right -exp digits from the coefficient; the exp will be 0
    1203    ind = -exp;	// 1 <= ind <= 34; ind is a synonym for 'x' 
    1204    // (number of digits to be chopped off)
    1205    // chop off ind digits from the lower part of C1 
    1206    // FOR ROUND_TO_NEAREST, WE ADD 1/2 ULP(y) then truncate
    1207    // FOR ROUND_TO_ZERO, WE DON'T NEED TO ADD 1/2 ULP
    1208    // FOR ROUND_TO_POSITIVE_INFINITY, WE TRUNCATE, THEN ADD 1 IF POSITIVE
    1209    // FOR ROUND_TO_NEGATIVE_INFINITY, WE TRUNCATE, THEN ADD 1 IF NEGATIVE
    1210    //tmp64 = C1.w[0];
    1211    // if (ind <= 19) {
    1212    //   C1.w[0] = C1.w[0] + midpoint64[ind - 1];
    1213    // } else {
    1214    //   C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
    1215    //   C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
    1216    // }
    1217    // if (C1.w[0] < tmp64) C1.w[1]++;
    1218    // if carry-out from C1.w[0], increment C1.w[1]
    1219    // calculate C* and f*
    1220    // C* is actually floor(C*) in this case
    1221    // C* and f* need shifting and masking, as shown by
    1222    // shiftright128[] and maskhigh128[]
    1223    // 1 <= x <= 34
    1224    // kx = 10^(-x) = ten2mk128[ind - 1]
    1225    // C* = (C1 + 1/2 * 10^x) * 10^(-x)
    1226    // the approximation of 10^(-x) was rounded up to 118 bits
    1227    __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
    1228    if (ind - 1 <= 2) {	// 0 <= ind - 1 <= 2 => shift = 0
    1229      res.w[1] = P256.w[3];
    1230      res.w[0] = P256.w[2];
    1231      // if positive, the truncated value is already the correct result
    1232      if (x_sign) {	// if negative
    1233        // redundant fstar.w[3] = 0;
    1234        // redundant fstar.w[2] = 0;
    1235        // redundant fstar.w[1] = P256.w[1];
    1236        // redundant fstar.w[0] = P256.w[0];
    1237        // fraction f* > 10^(-x) <=> inexact
    1238        // f* is in the right position to be compared with
    1239        // 10^(-x) from ten2mk128[]
    1240        if ((P256.w[1] > ten2mk128[ind - 1].w[1])
    1241  	  || (P256.w[1] == ten2mk128[ind - 1].w[1]
    1242  	      && (P256.w[0] >= ten2mk128[ind - 1].w[0]))) {
    1243  	if (++res.w[0] == 0) {
    1244  	  res.w[1]++;
    1245  	}
    1246        }
    1247      }
    1248    } else if (ind - 1 <= 21) {	// 3 <= ind - 1 <= 21 => 3 <= shift <= 63
    1249      shift = shiftright128[ind - 1];	// 0 <= shift <= 102
    1250      res.w[1] = (P256.w[3] >> shift);
    1251      res.w[0] = (P256.w[3] << (64 - shift)) | (P256.w[2] >> shift);
    1252      // if positive, the truncated value is already the correct result
    1253      if (x_sign) {	// if negative
    1254        // redundant fstar.w[3] = 0;
    1255        fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
    1256        fstar.w[1] = P256.w[1];
    1257        fstar.w[0] = P256.w[0];
    1258        // fraction f* > 10^(-x) <=> inexact
    1259        // f* is in the right position to be compared with
    1260        // 10^(-x) from ten2mk128[]
    1261        if (fstar.w[2] || fstar.w[1] > ten2mk128[ind - 1].w[1] ||
    1262  	  (fstar.w[1] == ten2mk128[ind - 1].w[1] &&
    1263  	   fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
    1264  	if (++res.w[0] == 0) {
    1265  	  res.w[1]++;
    1266  	}
    1267        }
    1268      }
    1269    } else {	// 22 <= ind - 1 <= 33
    1270      shift = shiftright128[ind - 1] - 64;	// 2 <= shift <= 38
    1271      res.w[1] = 0;
    1272      res.w[0] = P256.w[3] >> shift;
    1273      // if positive, the truncated value is already the correct result
    1274      if (x_sign) {	// if negative
    1275        fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
    1276        fstar.w[2] = P256.w[2];
    1277        fstar.w[1] = P256.w[1];
    1278        fstar.w[0] = P256.w[0];
    1279        // fraction f* > 10^(-x) <=> inexact
    1280        // f* is in the right position to be compared with
    1281        // 10^(-x) from ten2mk128[]
    1282        if (fstar.w[3] || fstar.w[2]
    1283  	  || fstar.w[1] > ten2mk128[ind - 1].w[1]
    1284  	  || (fstar.w[1] == ten2mk128[ind - 1].w[1]
    1285  	      && fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
    1286  	if (++res.w[0] == 0) {
    1287  	  res.w[1]++;
    1288  	}
    1289        }
    1290      }
    1291    }
    1292    res.w[1] = x_sign | 0x3040000000000000ull | res.w[1];
    1293    BID_RETURN (res);
    1294  } else {	// if exp < 0 and q + exp <= 0
    1295    if (x_sign) {	// negative rounds down to -1.0
    1296      res.w[1] = 0xb040000000000000ull;
    1297      res.w[0] = 0x0000000000000001ull;
    1298    } else {	// positive rpunds down to +0.0
    1299      res.w[1] = 0x3040000000000000ull;
    1300      res.w[0] = 0x0000000000000000ull;
    1301    }
    1302    BID_RETURN (res);
    1303  }
    1304  }
    1305  
    1306  /*****************************************************************************
    1307   *  BID128_round_integral_positive
    1308   ****************************************************************************/
    1309  
    1310  BID128_FUNCTION_ARG1_NORND (bid128_round_integral_positive, x)
    1311  
    1312       UINT128 res;
    1313       UINT64 x_sign;
    1314       UINT64 x_exp;
    1315       int exp;			// unbiased exponent
    1316    // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo 
    1317    // (all are UINT64)
    1318       BID_UI64DOUBLE tmp1;
    1319       unsigned int x_nr_bits;
    1320       int q, ind, shift;
    1321       UINT128 C1;
    1322    // UINT128 res is C* at first - represents up to 34 decimal digits ~ 
    1323    // 113 bits
    1324       UINT256 fstar;
    1325       UINT256 P256;
    1326  
    1327    // check for NaN or Infinity
    1328  if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
    1329      // x is special
    1330  if ((x.w[1] & MASK_NAN) == MASK_NAN) {	// x is NAN
    1331    // if x = NaN, then res = Q (x)
    1332    // check first for non-canonical NaN payload
    1333    if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
    1334        (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
    1335         (x.w[0] > 0x38c15b09ffffffffull))) {
    1336      x.w[1] = x.w[1] & 0xffffc00000000000ull;
    1337      x.w[0] = 0x0ull;
    1338    }
    1339    if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {	// x is SNAN
    1340      // set invalid flag
    1341      *pfpsf |= INVALID_EXCEPTION;
    1342      // return quiet (x)
    1343      res.w[1] = x.w[1] & 0xfc003fffffffffffull;	// clear out also G[6]-G[16]
    1344      res.w[0] = x.w[0];
    1345    } else {	// x is QNaN
    1346      // return x
    1347      res.w[1] = x.w[1] & 0xfc003fffffffffffull;	// clear out G[6]-G[16]
    1348      res.w[0] = x.w[0];
    1349    }
    1350    BID_RETURN (res)
    1351  } else {	// x is not a NaN, so it must be infinity
    1352    if ((x.w[1] & MASK_SIGN) == 0x0ull) {	// x is +inf
    1353      // return +inf
    1354      res.w[1] = 0x7800000000000000ull;
    1355      res.w[0] = 0x0000000000000000ull;
    1356    } else {	// x is -inf 
    1357      // return -inf
    1358      res.w[1] = 0xf800000000000000ull;
    1359      res.w[0] = 0x0000000000000000ull;
    1360    }
    1361    BID_RETURN (res);
    1362  }
    1363  }
    1364    // unpack x
    1365  x_sign = x.w[1] & MASK_SIGN;	// 0 for positive, MASK_SIGN for negative
    1366  C1.w[1] = x.w[1] & MASK_COEFF;
    1367  C1.w[0] = x.w[0];
    1368  
    1369    // check for non-canonical values (treated as zero)
    1370  if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {	// G0_G1=11
    1371    // non-canonical
    1372    x_exp = (x.w[1] << 2) & MASK_EXP;	// biased and shifted left 49 bits
    1373    C1.w[1] = 0;	// significand high
    1374    C1.w[0] = 0;	// significand low
    1375  } else {	// G0_G1 != 11
    1376    x_exp = x.w[1] & MASK_EXP;	// biased and shifted left 49 bits
    1377    if (C1.w[1] > 0x0001ed09bead87c0ull ||
    1378        (C1.w[1] == 0x0001ed09bead87c0ull
    1379         && C1.w[0] > 0x378d8e63ffffffffull)) {
    1380      // x is non-canonical if coefficient is larger than 10^34 -1
    1381      C1.w[1] = 0;
    1382      C1.w[0] = 0;
    1383    } else {	// canonical
    1384      ;
    1385    }
    1386  }
    1387  
    1388    // test for input equal to zero
    1389  if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
    1390    // x is 0
    1391    // return 0 preserving the sign bit and the preferred exponent 
    1392    // of MAX(Q(x), 0)
    1393    if (x_exp <= (0x1820ull << 49)) {
    1394      res.w[1] = (x.w[1] & 0x8000000000000000ull) | 0x3040000000000000ull;
    1395    } else {
    1396      res.w[1] = x_sign | x_exp;
    1397    }
    1398    res.w[0] = 0x0000000000000000ull;
    1399    BID_RETURN (res);
    1400  }
    1401    // x is not special and is not zero
    1402  
    1403    // if (exp <= -p) return -0.0 or +1.0
    1404  if (x_exp <= 0x2ffc000000000000ull) {	// 0x2ffc000000000000ull == -34
    1405    if (x_sign) {
    1406      // if negative, return negative 0, because we know the coefficient 
    1407      // is non-zero (would have been caught above)
    1408      res.w[1] = 0xb040000000000000ull;
    1409      res.w[0] = 0x0000000000000000ull;
    1410    } else {
    1411      // if positive, return positive 1, because we know coefficient is 
    1412      // non-zero (would have been caught above)
    1413      res.w[1] = 0x3040000000000000ull;
    1414      res.w[0] = 0x0000000000000001ull;
    1415    }
    1416    BID_RETURN (res);
    1417  }
    1418    // q = nr. of decimal digits in x
    1419    // determine first the nr. of bits in x
    1420  if (C1.w[1] == 0) {
    1421    if (C1.w[0] >= 0x0020000000000000ull) {	// x >= 2^53
    1422      // split 64-bit value in two 32-bit halves to avoid rounding errors
    1423      if (C1.w[0] >= 0x0000000100000000ull) {	// x >= 2^32
    1424        tmp1.d = (double) (C1.w[0] >> 32);	// exact conversion
    1425        x_nr_bits =
    1426  	33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1427      } else {	// x < 2^32
    1428        tmp1.d = (double) (C1.w[0]);	// exact conversion
    1429        x_nr_bits =
    1430  	1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1431      }
    1432    } else {	// if x < 2^53
    1433      tmp1.d = (double) C1.w[0];	// exact conversion
    1434      x_nr_bits =
    1435        1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1436    }
    1437  } else {	// C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
    1438    tmp1.d = (double) C1.w[1];	// exact conversion
    1439    x_nr_bits =
    1440      65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1441  }
    1442  
    1443  q = nr_digits[x_nr_bits - 1].digits;
    1444  if (q == 0) {
    1445    q = nr_digits[x_nr_bits - 1].digits1;
    1446    if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi ||
    1447        (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi &&
    1448         C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
    1449      q++;
    1450  }
    1451  exp = (x_exp >> 49) - 6176;
    1452  if (exp >= 0) {	// -exp <= 0
    1453    // the argument is an integer already
    1454    res.w[1] = x.w[1];
    1455    res.w[0] = x.w[0];
    1456    BID_RETURN (res);
    1457  } else if ((q + exp) > 0) {	// exp < 0 and 1 <= -exp < q
    1458    // need to shift right -exp digits from the coefficient; exp will be 0
    1459    ind = -exp;	// 1 <= ind <= 34; ind is a synonym for 'x' 
    1460    // (number of digits to be chopped off)
    1461    // chop off ind digits from the lower part of C1 
    1462    // FOR ROUND_TO_NEAREST, WE ADD 1/2 ULP(y) then truncate
    1463    // FOR ROUND_TO_ZERO, WE DON'T NEED TO ADD 1/2 ULP
    1464    // FOR ROUND_TO_POSITIVE_INFINITY, WE TRUNCATE, THEN ADD 1 IF POSITIVE
    1465    // FOR ROUND_TO_NEGATIVE_INFINITY, WE TRUNCATE, THEN ADD 1 IF NEGATIVE
    1466    // tmp64 = C1.w[0];
    1467    // if (ind <= 19) {
    1468    //   C1.w[0] = C1.w[0] + midpoint64[ind - 1];
    1469    // } else {
    1470    //   C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
    1471    //   C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
    1472    // }
    1473    // if (C1.w[0] < tmp64) C1.w[1]++;  
    1474    // if carry-out from C1.w[0], increment C1.w[1]
    1475    // calculate C* and f*
    1476    // C* is actually floor(C*) in this case
    1477    // C* and f* need shifting and masking, as shown by
    1478    // shiftright128[] and maskhigh128[]
    1479    // 1 <= x <= 34
    1480    // kx = 10^(-x) = ten2mk128[ind - 1]
    1481    // C* = C1 * 10^(-x)
    1482    // the approximation of 10^(-x) was rounded up to 118 bits
    1483    __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
    1484    if (ind - 1 <= 2) {	// 0 <= ind - 1 <= 2 => shift = 0
    1485      res.w[1] = P256.w[3];
    1486      res.w[0] = P256.w[2];
    1487      // if negative, the truncated value is already the correct result
    1488      if (!x_sign) {	// if positive
    1489        // redundant fstar.w[3] = 0;
    1490        // redundant fstar.w[2] = 0;
    1491        // redundant fstar.w[1] = P256.w[1]; 
    1492        // redundant fstar.w[0] = P256.w[0];
    1493        // fraction f* > 10^(-x) <=> inexact
    1494        // f* is in the right position to be compared with 
    1495        // 10^(-x) from ten2mk128[]
    1496        if ((P256.w[1] > ten2mk128[ind - 1].w[1])
    1497  	  || (P256.w[1] == ten2mk128[ind - 1].w[1]
    1498  	      && (P256.w[0] >= ten2mk128[ind - 1].w[0]))) {
    1499  	if (++res.w[0] == 0) {
    1500  	  res.w[1]++;
    1501  	}
    1502        }
    1503      }
    1504    } else if (ind - 1 <= 21) {	// 3 <= ind - 1 <= 21 => 3 <= shift <= 63
    1505      shift = shiftright128[ind - 1];	// 3 <= shift <= 63
    1506      res.w[1] = (P256.w[3] >> shift);
    1507      res.w[0] = (P256.w[3] << (64 - shift)) | (P256.w[2] >> shift);
    1508      // if negative, the truncated value is already the correct result
    1509      if (!x_sign) {	// if positive
    1510        // redundant fstar.w[3] = 0;
    1511        fstar.w[2] = P256.w[2] & maskhigh128[ind - 1];
    1512        fstar.w[1] = P256.w[1];
    1513        fstar.w[0] = P256.w[0];
    1514        // fraction f* > 10^(-x) <=> inexact
    1515        // f* is in the right position to be compared with 
    1516        // 10^(-x) from ten2mk128[]
    1517        if (fstar.w[2] || fstar.w[1] > ten2mk128[ind - 1].w[1] ||
    1518  	  (fstar.w[1] == ten2mk128[ind - 1].w[1] &&
    1519  	   fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
    1520  	if (++res.w[0] == 0) {
    1521  	  res.w[1]++;
    1522  	}
    1523        }
    1524      }
    1525    } else {	// 22 <= ind - 1 <= 33
    1526      shift = shiftright128[ind - 1] - 64;	// 2 <= shift <= 38
    1527      res.w[1] = 0;
    1528      res.w[0] = P256.w[3] >> shift;
    1529      // if negative, the truncated value is already the correct result
    1530      if (!x_sign) {	// if positive
    1531        fstar.w[3] = P256.w[3] & maskhigh128[ind - 1];
    1532        fstar.w[2] = P256.w[2];
    1533        fstar.w[1] = P256.w[1];
    1534        fstar.w[0] = P256.w[0];
    1535        // fraction f* > 10^(-x) <=> inexact
    1536        // f* is in the right position to be compared with 
    1537        // 10^(-x) from ten2mk128[]
    1538        if (fstar.w[3] || fstar.w[2]
    1539  	  || fstar.w[1] > ten2mk128[ind - 1].w[1]
    1540  	  || (fstar.w[1] == ten2mk128[ind - 1].w[1]
    1541  	      && fstar.w[0] >= ten2mk128[ind - 1].w[0])) {
    1542  	if (++res.w[0] == 0) {
    1543  	  res.w[1]++;
    1544  	}
    1545        }
    1546      }
    1547    }
    1548    res.w[1] = x_sign | 0x3040000000000000ull | res.w[1];
    1549    BID_RETURN (res);
    1550  } else {	// if exp < 0 and q + exp <= 0
    1551    if (x_sign) {	// negative rounds up to -0.0
    1552      res.w[1] = 0xb040000000000000ull;
    1553      res.w[0] = 0x0000000000000000ull;
    1554    } else {	// positive rpunds up to +1.0
    1555      res.w[1] = 0x3040000000000000ull;
    1556      res.w[0] = 0x0000000000000001ull;
    1557    }
    1558    BID_RETURN (res);
    1559  }
    1560  }
    1561  
    1562  /*****************************************************************************
    1563   *  BID128_round_integral_zero
    1564   ****************************************************************************/
    1565  
    1566  BID128_FUNCTION_ARG1_NORND (bid128_round_integral_zero, x)
    1567  
    1568       UINT128 res;
    1569       UINT64 x_sign;
    1570       UINT64 x_exp;
    1571       int exp;			// unbiased exponent
    1572    // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo
    1573    // (all are UINT64)
    1574       BID_UI64DOUBLE tmp1;
    1575       unsigned int x_nr_bits;
    1576       int q, ind, shift;
    1577       UINT128 C1;
    1578    // UINT128 res is C* at first - represents up to 34 decimal digits ~
    1579    // 113 bits
    1580       UINT256 P256;
    1581  
    1582    // check for NaN or Infinity
    1583  if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
    1584      // x is special
    1585  if ((x.w[1] & MASK_NAN) == MASK_NAN) {	// x is NAN
    1586    // if x = NaN, then res = Q (x)
    1587    // check first for non-canonical NaN payload
    1588    if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
    1589        (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
    1590         (x.w[0] > 0x38c15b09ffffffffull))) {
    1591      x.w[1] = x.w[1] & 0xffffc00000000000ull;
    1592      x.w[0] = 0x0ull;
    1593    }
    1594    if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {	// x is SNAN
    1595      // set invalid flag
    1596      *pfpsf |= INVALID_EXCEPTION;
    1597      // return quiet (x)
    1598      res.w[1] = x.w[1] & 0xfc003fffffffffffull;	// clear out also G[6]-G[16]
    1599      res.w[0] = x.w[0];
    1600    } else {	// x is QNaN
    1601      // return x
    1602      res.w[1] = x.w[1] & 0xfc003fffffffffffull;	// clear out G[6]-G[16]
    1603      res.w[0] = x.w[0];
    1604    }
    1605    BID_RETURN (res)
    1606  } else {	// x is not a NaN, so it must be infinity
    1607    if ((x.w[1] & MASK_SIGN) == 0x0ull) {	// x is +inf
    1608      // return +inf
    1609      res.w[1] = 0x7800000000000000ull;
    1610      res.w[0] = 0x0000000000000000ull;
    1611    } else {	// x is -inf 
    1612      // return -inf
    1613      res.w[1] = 0xf800000000000000ull;
    1614      res.w[0] = 0x0000000000000000ull;
    1615    }
    1616    BID_RETURN (res);
    1617  }
    1618  }
    1619    // unpack x
    1620  x_sign = x.w[1] & MASK_SIGN;	// 0 for positive, MASK_SIGN for negative
    1621  C1.w[1] = x.w[1] & MASK_COEFF;
    1622  C1.w[0] = x.w[0];
    1623  
    1624    // check for non-canonical values (treated as zero)
    1625  if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {	// G0_G1=11
    1626    // non-canonical
    1627    x_exp = (x.w[1] << 2) & MASK_EXP;	// biased and shifted left 49 bits
    1628    C1.w[1] = 0;	// significand high
    1629    C1.w[0] = 0;	// significand low
    1630  } else {	// G0_G1 != 11
    1631    x_exp = x.w[1] & MASK_EXP;	// biased and shifted left 49 bits
    1632    if (C1.w[1] > 0x0001ed09bead87c0ull ||
    1633        (C1.w[1] == 0x0001ed09bead87c0ull
    1634         && C1.w[0] > 0x378d8e63ffffffffull)) {
    1635      // x is non-canonical if coefficient is larger than 10^34 -1
    1636      C1.w[1] = 0;
    1637      C1.w[0] = 0;
    1638    } else {	// canonical
    1639      ;
    1640    }
    1641  }
    1642  
    1643    // test for input equal to zero
    1644  if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
    1645    // x is 0
    1646    // return 0 preserving the sign bit and the preferred exponent
    1647    // of MAX(Q(x), 0)
    1648    if (x_exp <= (0x1820ull << 49)) {
    1649      res.w[1] = (x.w[1] & 0x8000000000000000ull) | 0x3040000000000000ull;
    1650    } else {
    1651      res.w[1] = x_sign | x_exp;
    1652    }
    1653    res.w[0] = 0x0000000000000000ull;
    1654    BID_RETURN (res);
    1655  }
    1656    // x is not special and is not zero
    1657  
    1658    // if (exp <= -p) return -0.0 or +0.0
    1659  if (x_exp <= 0x2ffc000000000000ull) {	// 0x2ffc000000000000ull == -34
    1660    res.w[1] = x_sign | 0x3040000000000000ull;
    1661    res.w[0] = 0x0000000000000000ull;
    1662    BID_RETURN (res);
    1663  }
    1664    // q = nr. of decimal digits in x
    1665    // determine first the nr. of bits in x
    1666  if (C1.w[1] == 0) {
    1667    if (C1.w[0] >= 0x0020000000000000ull) {	// x >= 2^53
    1668      // split the 64-bit value in two 32-bit halves to avoid rounding errors
    1669      if (C1.w[0] >= 0x0000000100000000ull) {	// x >= 2^32
    1670        tmp1.d = (double) (C1.w[0] >> 32);	// exact conversion
    1671        x_nr_bits =
    1672  	33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1673      } else {	// x < 2^32
    1674        tmp1.d = (double) (C1.w[0]);	// exact conversion
    1675        x_nr_bits =
    1676  	1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1677      }
    1678    } else {	// if x < 2^53
    1679      tmp1.d = (double) C1.w[0];	// exact conversion
    1680      x_nr_bits =
    1681        1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1682    }
    1683  } else {	// C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
    1684    tmp1.d = (double) C1.w[1];	// exact conversion
    1685    x_nr_bits =
    1686      65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1687  }
    1688  
    1689  q = nr_digits[x_nr_bits - 1].digits;
    1690  if (q == 0) {
    1691    q = nr_digits[x_nr_bits - 1].digits1;
    1692    if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi ||
    1693        (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi &&
    1694         C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
    1695      q++;
    1696  }
    1697  exp = (x_exp >> 49) - 6176;
    1698  if (exp >= 0) {	// -exp <= 0
    1699    // the argument is an integer already
    1700    res.w[1] = x.w[1];
    1701    res.w[0] = x.w[0];
    1702    BID_RETURN (res);
    1703  } else if ((q + exp) > 0) {	// exp < 0 and 1 <= -exp < q
    1704    // need to shift right -exp digits from the coefficient; the exp will be 0
    1705    ind = -exp;	// 1 <= ind <= 34; ind is a synonym for 'x'
    1706    // (number of digits to be chopped off)
    1707    // chop off ind digits from the lower part of C1 
    1708    // FOR ROUND_TO_NEAREST, WE ADD 1/2 ULP(y) then truncate
    1709    // FOR ROUND_TO_ZERO, WE DON'T NEED TO ADD 1/2 ULP
    1710    // FOR ROUND_TO_POSITIVE_INFINITY, WE TRUNCATE, THEN ADD 1 IF POSITIVE
    1711    // FOR ROUND_TO_NEGATIVE_INFINITY, WE TRUNCATE, THEN ADD 1 IF NEGATIVE
    1712    //tmp64 = C1.w[0];
    1713    // if (ind <= 19) {
    1714    //   C1.w[0] = C1.w[0] + midpoint64[ind - 1];
    1715    // } else {
    1716    //   C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
    1717    //   C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
    1718    // }
    1719    // if (C1.w[0] < tmp64) C1.w[1]++;  
    1720    // if carry-out from C1.w[0], increment C1.w[1]
    1721    // calculate C* and f*
    1722    // C* is actually floor(C*) in this case
    1723    // C* and f* need shifting and masking, as shown by
    1724    // shiftright128[] and maskhigh128[]
    1725    // 1 <= x <= 34
    1726    // kx = 10^(-x) = ten2mk128[ind - 1]
    1727    // C* = (C1 + 1/2 * 10^x) * 10^(-x)
    1728    // the approximation of 10^(-x) was rounded up to 118 bits
    1729    __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
    1730    if (ind - 1 <= 2) {	// 0 <= ind - 1 <= 2 => shift = 0
    1731      res.w[1] = P256.w[3];
    1732      res.w[0] = P256.w[2];
    1733    } else if (ind - 1 <= 21) {	// 3 <= ind - 1 <= 21 => 3 <= shift <= 63
    1734      shift = shiftright128[ind - 1];	// 3 <= shift <= 63
    1735      res.w[1] = (P256.w[3] >> shift);
    1736      res.w[0] = (P256.w[3] << (64 - shift)) | (P256.w[2] >> shift);
    1737    } else {	// 22 <= ind - 1 <= 33
    1738      shift = shiftright128[ind - 1] - 64;	// 2 <= shift <= 38
    1739      res.w[1] = 0;
    1740      res.w[0] = P256.w[3] >> shift;
    1741    }
    1742    res.w[1] = x_sign | 0x3040000000000000ull | res.w[1];
    1743    BID_RETURN (res);
    1744  } else {	// if exp < 0 and q + exp <= 0 the result is +0 or -0
    1745    res.w[1] = x_sign | 0x3040000000000000ull;
    1746    res.w[0] = 0x0000000000000000ull;
    1747    BID_RETURN (res);
    1748  }
    1749  }
    1750  
    1751  /*****************************************************************************
    1752   *  BID128_round_integral_nearest_away
    1753   ****************************************************************************/
    1754  
    1755  BID128_FUNCTION_ARG1_NORND (bid128_round_integral_nearest_away, x)
    1756  
    1757       UINT128 res;
    1758       UINT64 x_sign;
    1759       UINT64 x_exp;
    1760       int exp;			// unbiased exponent
    1761    // Note: C1.w[1], C1.w[0] represent x_signif_hi, x_signif_lo 
    1762    // (all are UINT64)
    1763       UINT64 tmp64;
    1764       BID_UI64DOUBLE tmp1;
    1765       unsigned int x_nr_bits;
    1766       int q, ind, shift;
    1767       UINT128 C1;
    1768    // UINT128 res is C* at first - represents up to 34 decimal digits ~ 
    1769    // 113 bits
    1770    // UINT256 fstar;
    1771       UINT256 P256;
    1772  
    1773    // check for NaN or Infinity
    1774  if ((x.w[1] & MASK_SPECIAL) == MASK_SPECIAL) {
    1775      // x is special
    1776  if ((x.w[1] & MASK_NAN) == MASK_NAN) {	// x is NAN
    1777    // if x = NaN, then res = Q (x)
    1778    // check first for non-canonical NaN payload
    1779    if (((x.w[1] & 0x00003fffffffffffull) > 0x0000314dc6448d93ull) ||
    1780        (((x.w[1] & 0x00003fffffffffffull) == 0x0000314dc6448d93ull) &&
    1781         (x.w[0] > 0x38c15b09ffffffffull))) {
    1782      x.w[1] = x.w[1] & 0xffffc00000000000ull;
    1783      x.w[0] = 0x0ull;
    1784    }
    1785    if ((x.w[1] & MASK_SNAN) == MASK_SNAN) {	// x is SNAN
    1786      // set invalid flag
    1787      *pfpsf |= INVALID_EXCEPTION;
    1788      // return quiet (x)
    1789      res.w[1] = x.w[1] & 0xfc003fffffffffffull;	// clear out also G[6]-G[16]
    1790      res.w[0] = x.w[0];
    1791    } else {	// x is QNaN
    1792      // return x
    1793      res.w[1] = x.w[1] & 0xfc003fffffffffffull;	// clear out G[6]-G[16]
    1794      res.w[0] = x.w[0];
    1795    }
    1796    BID_RETURN (res)
    1797  } else {	// x is not a NaN, so it must be infinity
    1798    if ((x.w[1] & MASK_SIGN) == 0x0ull) {	// x is +inf
    1799      // return +inf
    1800      res.w[1] = 0x7800000000000000ull;
    1801      res.w[0] = 0x0000000000000000ull;
    1802    } else {	// x is -inf 
    1803      // return -inf
    1804      res.w[1] = 0xf800000000000000ull;
    1805      res.w[0] = 0x0000000000000000ull;
    1806    }
    1807    BID_RETURN (res);
    1808  }
    1809  }
    1810    // unpack x
    1811  x_sign = x.w[1] & MASK_SIGN;	// 0 for positive, MASK_SIGN for negative
    1812  C1.w[1] = x.w[1] & MASK_COEFF;
    1813  C1.w[0] = x.w[0];
    1814  
    1815    // check for non-canonical values (treated as zero)
    1816  if ((x.w[1] & 0x6000000000000000ull) == 0x6000000000000000ull) {	// G0_G1=11
    1817    // non-canonical
    1818    x_exp = (x.w[1] << 2) & MASK_EXP;	// biased and shifted left 49 bits
    1819    C1.w[1] = 0;	// significand high
    1820    C1.w[0] = 0;	// significand low
    1821  } else {	// G0_G1 != 11
    1822    x_exp = x.w[1] & MASK_EXP;	// biased and shifted left 49 bits
    1823    if (C1.w[1] > 0x0001ed09bead87c0ull ||
    1824        (C1.w[1] == 0x0001ed09bead87c0ull
    1825         && C1.w[0] > 0x378d8e63ffffffffull)) {
    1826      // x is non-canonical if coefficient is larger than 10^34 -1
    1827      C1.w[1] = 0;
    1828      C1.w[0] = 0;
    1829    } else {	// canonical
    1830      ;
    1831    }
    1832  }
    1833  
    1834    // test for input equal to zero
    1835  if ((C1.w[1] == 0x0ull) && (C1.w[0] == 0x0ull)) {
    1836    // x is 0
    1837    // return 0 preserving the sign bit and the preferred exponent
    1838    // of MAX(Q(x), 0)
    1839    if (x_exp <= (0x1820ull << 49)) {
    1840      res.w[1] = (x.w[1] & 0x8000000000000000ull) | 0x3040000000000000ull;
    1841    } else {
    1842      res.w[1] = x_sign | x_exp;
    1843    }
    1844    res.w[0] = 0x0000000000000000ull;
    1845    BID_RETURN (res);
    1846  }
    1847    // x is not special and is not zero
    1848  
    1849    // if (exp <= -(p+1)) return 0.0
    1850  if (x_exp <= 0x2ffa000000000000ull) {	// 0x2ffa000000000000ull == -35
    1851    res.w[1] = x_sign | 0x3040000000000000ull;
    1852    res.w[0] = 0x0000000000000000ull;
    1853    BID_RETURN (res);
    1854  }
    1855    // q = nr. of decimal digits in x
    1856    //  determine first the nr. of bits in x
    1857  if (C1.w[1] == 0) {
    1858    if (C1.w[0] >= 0x0020000000000000ull) {	// x >= 2^53
    1859      // split the 64-bit value in two 32-bit halves to avoid rounding errors
    1860      if (C1.w[0] >= 0x0000000100000000ull) {	// x >= 2^32
    1861        tmp1.d = (double) (C1.w[0] >> 32);	// exact conversion
    1862        x_nr_bits =
    1863  	33 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1864      } else {	// x < 2^32
    1865        tmp1.d = (double) (C1.w[0]);	// exact conversion
    1866        x_nr_bits =
    1867  	1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1868      }
    1869    } else {	// if x < 2^53
    1870      tmp1.d = (double) C1.w[0];	// exact conversion
    1871      x_nr_bits =
    1872        1 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1873    }
    1874  } else {	// C1.w[1] != 0 => nr. bits = 64 + nr_bits (C1.w[1])
    1875    tmp1.d = (double) C1.w[1];	// exact conversion
    1876    x_nr_bits =
    1877      65 + ((((unsigned int) (tmp1.ui64 >> 52)) & 0x7ff) - 0x3ff);
    1878  }
    1879  
    1880  q = nr_digits[x_nr_bits - 1].digits;
    1881  if (q == 0) {
    1882    q = nr_digits[x_nr_bits - 1].digits1;
    1883    if (C1.w[1] > nr_digits[x_nr_bits - 1].threshold_hi ||
    1884        (C1.w[1] == nr_digits[x_nr_bits - 1].threshold_hi &&
    1885         C1.w[0] >= nr_digits[x_nr_bits - 1].threshold_lo))
    1886      q++;
    1887  }
    1888  exp = (x_exp >> 49) - 6176;
    1889  if (exp >= 0) {	// -exp <= 0
    1890    // the argument is an integer already
    1891    res.w[1] = x.w[1];
    1892    res.w[0] = x.w[0];
    1893    BID_RETURN (res);
    1894  } else if ((q + exp) >= 0) {	// exp < 0 and 1 <= -exp <= q
    1895    // need to shift right -exp digits from the coefficient; the exp will be 0
    1896    ind = -exp;	// 1 <= ind <= 34; ind is a synonym for 'x'
    1897    // chop off ind digits from the lower part of C1 
    1898    // C1 = C1 + 1/2 * 10^x where the result C1 fits in 127 bits
    1899    tmp64 = C1.w[0];
    1900    if (ind <= 19) {
    1901      C1.w[0] = C1.w[0] + midpoint64[ind - 1];
    1902    } else {
    1903      C1.w[0] = C1.w[0] + midpoint128[ind - 20].w[0];
    1904      C1.w[1] = C1.w[1] + midpoint128[ind - 20].w[1];
    1905    }
    1906    if (C1.w[0] < tmp64)
    1907      C1.w[1]++;
    1908    // calculate C* and f*
    1909    // C* is actually floor(C*) in this case
    1910    // C* and f* need shifting and masking, as shown by
    1911    // shiftright128[] and maskhigh128[]
    1912    // 1 <= x <= 34
    1913    // kx = 10^(-x) = ten2mk128[ind - 1]
    1914    // C* = (C1 + 1/2 * 10^x) * 10^(-x)
    1915    // the approximation of 10^(-x) was rounded up to 118 bits
    1916    __mul_128x128_to_256 (P256, C1, ten2mk128[ind - 1]);
    1917    // the top Ex bits of 10^(-x) are T* = ten2mk128trunc[ind], e.g.
    1918    // if x=1, T*=ten2mk128trunc[0]=0x19999999999999999999999999999999
    1919    // if (0 < f* < 10^(-x)) then the result is a midpoint
    1920    //   if floor(C*) is even then C* = floor(C*) - logical right
    1921    //       shift; C* has p decimal digits, correct by Prop. 1)
    1922    //   else if floor(C*) is odd C* = floor(C*)-1 (logical right
    1923    //       shift; C* has p decimal digits, correct by Pr. 1)
    1924    // else
    1925    //   C* = floor(C*) (logical right shift; C has p decimal digits,
    1926    //       correct by Property 1)
    1927    // n = C* * 10^(e+x)
    1928  
    1929    // shift right C* by Ex-128 = shiftright128[ind]
    1930    if (ind - 1 <= 2) {	// 0 <= ind - 1 <= 2 => shift = 0
    1931      res.w[1] = P256.w[3];
    1932      res.w[0] = P256.w[2];
    1933    } else if (ind - 1 <= 21) {	// 3 <= ind - 1 <= 21 => 3 <= shift <= 63
    1934      shift = shiftright128[ind - 1];	// 3 <= shift <= 63
    1935      res.w[0] = (P256.w[3] << (64 - shift)) | (P256.w[2] >> shift);
    1936      res.w[1] = (P256.w[3] >> shift);
    1937    } else {	// 22 <= ind - 1 <= 33
    1938      shift = shiftright128[ind - 1];	// 2 <= shift <= 38
    1939      res.w[1] = 0;
    1940      res.w[0] = (P256.w[3] >> (shift - 64));	// 2 <= shift - 64 <= 38
    1941    }
    1942    // if the result was a midpoint, it was already rounded away from zero
    1943    res.w[1] |= x_sign | 0x3040000000000000ull;
    1944    BID_RETURN (res);
    1945  } else {	// if ((q + exp) < 0) <=> q < -exp
    1946    // the result is +0 or -0
    1947    res.w[1] = x_sign | 0x3040000000000000ull;
    1948    res.w[0] = 0x0000000000000000ull;
    1949    BID_RETURN (res);
    1950  }
    1951  }