Home | History | Annotate | Line # | Download | only in libbid
      1  1.12  mrg /* Copyright (C) 2007-2022 Free Software Foundation, Inc.
      2   1.1  mrg 
      3   1.1  mrg This file is part of GCC.
      4   1.1  mrg 
      5   1.1  mrg GCC is free software; you can redistribute it and/or modify it under
      6   1.1  mrg the terms of the GNU General Public License as published by the Free
      7   1.1  mrg Software Foundation; either version 3, or (at your option) any later
      8   1.1  mrg version.
      9   1.1  mrg 
     10   1.1  mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
     11   1.1  mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
     12   1.1  mrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
     13   1.1  mrg for more details.
     14   1.1  mrg 
     15   1.1  mrg Under Section 7 of GPL version 3, you are granted additional
     16   1.1  mrg permissions described in the GCC Runtime Library Exception, version
     17   1.1  mrg 3.1, as published by the Free Software Foundation.
     18   1.1  mrg 
     19   1.1  mrg You should have received a copy of the GNU General Public License and
     20   1.1  mrg a copy of the GCC Runtime Library Exception along with this program;
     21   1.1  mrg see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
     22   1.1  mrg <http://www.gnu.org/licenses/>.  */
     23   1.1  mrg 
     24   1.1  mrg /*****************************************************************************
     25   1.1  mrg  *    BID64 add
     26   1.1  mrg  *****************************************************************************
     27   1.1  mrg  *
     28   1.1  mrg  *  Algorithm description:
     29   1.1  mrg  *
     30   1.1  mrg  *   if(exponent_a < exponent_b)
     31   1.1  mrg  *       switch a, b
     32   1.1  mrg  *   diff_expon = exponent_a - exponent_b
     33   1.1  mrg  *   if(diff_expon > 16)
     34   1.1  mrg  *      return normalize(a)
     35   1.1  mrg  *   if(coefficient_a*10^diff_expon guaranteed below 2^62)
     36   1.1  mrg  *       S = sign_a*coefficient_a*10^diff_expon + sign_b*coefficient_b
     37   1.1  mrg  *       if(|S|<10^16)
     38   1.1  mrg  *           return get_BID64(sign(S),exponent_b,|S|)
     39   1.1  mrg  *       else
     40   1.1  mrg  *          determine number of extra digits in S (1, 2, or 3)
     41   1.1  mrg  *            return rounded result
     42   1.1  mrg  *   else // large exponent difference
     43   1.1  mrg  *       if(number_digits(coefficient_a*10^diff_expon) +/- 10^16)
     44   1.1  mrg  *          guaranteed the same as
     45   1.1  mrg  *          number_digits(coefficient_a*10^diff_expon) )
     46   1.1  mrg  *           S = normalize(coefficient_a + (sign_a^sign_b)*10^(16-diff_expon))
     47   1.1  mrg  *           corr = 10^16 + (sign_a^sign_b)*coefficient_b
     48   1.1  mrg  *           corr*10^exponent_b is rounded so it aligns with S*10^exponent_S
     49   1.1  mrg  *           return get_BID64(sign_a,exponent(S),S+rounded(corr))
     50   1.1  mrg  *       else
     51   1.1  mrg  *         add sign_a*coefficient_a*10^diff_expon, sign_b*coefficient_b
     52   1.1  mrg  *             in 128-bit integer arithmetic, then round to 16 decimal digits
     53   1.1  mrg  *
     54   1.1  mrg  *
     55   1.1  mrg  ****************************************************************************/
     56   1.1  mrg 
     57   1.1  mrg #include "bid_internal.h"
     58   1.1  mrg 
     59   1.1  mrg #if DECIMAL_CALL_BY_REFERENCE
     60   1.1  mrg void bid64_add (UINT64 * pres, UINT64 * px,
     61   1.1  mrg 		UINT64 *
     62   1.1  mrg 		py _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
     63   1.1  mrg 		_EXC_INFO_PARAM);
     64   1.1  mrg #else
     65   1.1  mrg UINT64 bid64_add (UINT64 x,
     66   1.1  mrg 		  UINT64 y _RND_MODE_PARAM _EXC_FLAGS_PARAM
     67   1.1  mrg 		  _EXC_MASKS_PARAM _EXC_INFO_PARAM);
     68   1.1  mrg #endif
     69   1.1  mrg 
     70   1.1  mrg #if DECIMAL_CALL_BY_REFERENCE
     71   1.1  mrg 
     72   1.1  mrg void
     73   1.1  mrg bid64_sub (UINT64 * pres, UINT64 * px,
     74   1.1  mrg 	   UINT64 *
     75   1.1  mrg 	   py _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
     76   1.1  mrg 	   _EXC_INFO_PARAM) {
     77   1.1  mrg   UINT64 y = *py;
     78   1.1  mrg #if !DECIMAL_GLOBAL_ROUNDING
     79   1.1  mrg   _IDEC_round rnd_mode = *prnd_mode;
     80   1.1  mrg #endif
     81   1.1  mrg   // check if y is not NaN
     82   1.1  mrg   if (((y & NAN_MASK64) != NAN_MASK64))
     83   1.1  mrg     y ^= 0x8000000000000000ull;
     84   1.1  mrg   bid64_add (pres, px,
     85   1.1  mrg 	     &y _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
     86   1.1  mrg 	     _EXC_INFO_ARG);
     87   1.1  mrg }
     88   1.1  mrg #else
     89   1.1  mrg 
     90   1.1  mrg UINT64
     91   1.1  mrg bid64_sub (UINT64 x,
     92   1.1  mrg 	   UINT64 y _RND_MODE_PARAM _EXC_FLAGS_PARAM
     93   1.1  mrg 	   _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
     94   1.1  mrg   // check if y is not NaN
     95   1.1  mrg   if (((y & NAN_MASK64) != NAN_MASK64))
     96   1.1  mrg     y ^= 0x8000000000000000ull;
     97   1.1  mrg 
     98   1.1  mrg   return bid64_add (x,
     99   1.1  mrg 		    y _RND_MODE_ARG _EXC_FLAGS_ARG _EXC_MASKS_ARG
    100   1.1  mrg 		    _EXC_INFO_ARG);
    101   1.1  mrg }
    102   1.1  mrg #endif
    103   1.1  mrg 
    104   1.1  mrg 
    105   1.1  mrg 
    106   1.1  mrg #if DECIMAL_CALL_BY_REFERENCE
    107   1.1  mrg 
    108   1.1  mrg void
    109   1.1  mrg bid64_add (UINT64 * pres, UINT64 * px,
    110   1.1  mrg 	   UINT64 *
    111   1.1  mrg 	   py _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM
    112   1.1  mrg 	   _EXC_INFO_PARAM) {
    113   1.1  mrg   UINT64 x, y;
    114   1.1  mrg #else
    115   1.1  mrg 
    116   1.1  mrg UINT64
    117   1.1  mrg bid64_add (UINT64 x,
    118   1.1  mrg 	   UINT64 y _RND_MODE_PARAM _EXC_FLAGS_PARAM
    119   1.1  mrg 	   _EXC_MASKS_PARAM _EXC_INFO_PARAM) {
    120   1.1  mrg #endif
    121   1.1  mrg 
    122   1.1  mrg   UINT128 CA, CT, CT_new;
    123   1.1  mrg   UINT64 sign_x, sign_y, coefficient_x, coefficient_y, C64_new;
    124   1.1  mrg   UINT64 valid_x, valid_y;
    125   1.1  mrg   UINT64 res;
    126   1.1  mrg   UINT64 sign_a, sign_b, coefficient_a, coefficient_b, sign_s, sign_ab,
    127   1.1  mrg     rem_a;
    128   1.1  mrg   UINT64 saved_ca, saved_cb, C0_64, C64, remainder_h, T1, carry, tmp;
    129   1.1  mrg   int_double tempx;
    130   1.1  mrg   int exponent_x, exponent_y, exponent_a, exponent_b, diff_dec_expon;
    131   1.1  mrg   int bin_expon_ca, extra_digits, amount, scale_k, scale_ca;
    132   1.1  mrg   unsigned rmode, status;
    133   1.1  mrg 
    134   1.1  mrg #if DECIMAL_CALL_BY_REFERENCE
    135   1.1  mrg #if !DECIMAL_GLOBAL_ROUNDING
    136   1.1  mrg   _IDEC_round rnd_mode = *prnd_mode;
    137   1.1  mrg #endif
    138   1.1  mrg   x = *px;
    139   1.1  mrg   y = *py;
    140   1.1  mrg #endif
    141   1.1  mrg 
    142   1.1  mrg   valid_x = unpack_BID64 (&sign_x, &exponent_x, &coefficient_x, x);
    143   1.1  mrg   valid_y = unpack_BID64 (&sign_y, &exponent_y, &coefficient_y, y);
    144   1.1  mrg 
    145   1.1  mrg   // unpack arguments, check for NaN or Infinity
    146   1.1  mrg   if (!valid_x) {
    147   1.1  mrg     // x is Inf. or NaN
    148   1.1  mrg 
    149   1.1  mrg     // test if x is NaN
    150   1.1  mrg     if ((x & NAN_MASK64) == NAN_MASK64) {
    151   1.1  mrg #ifdef SET_STATUS_FLAGS
    152   1.1  mrg       if (((x & SNAN_MASK64) == SNAN_MASK64)	// sNaN
    153   1.1  mrg 	  || ((y & SNAN_MASK64) == SNAN_MASK64))
    154   1.1  mrg 	__set_status_flags (pfpsf, INVALID_EXCEPTION);
    155   1.1  mrg #endif
    156   1.1  mrg       res = coefficient_x & QUIET_MASK64;
    157   1.1  mrg       BID_RETURN (res);
    158   1.1  mrg     }
    159   1.1  mrg     // x is Infinity?
    160   1.1  mrg     if ((x & INFINITY_MASK64) == INFINITY_MASK64) {
    161   1.1  mrg       // check if y is Inf
    162   1.1  mrg       if (((y & NAN_MASK64) == INFINITY_MASK64)) {
    163   1.1  mrg 	if (sign_x == (y & 0x8000000000000000ull)) {
    164   1.1  mrg 	  res = coefficient_x;
    165   1.1  mrg 	  BID_RETURN (res);
    166   1.1  mrg 	}
    167   1.1  mrg 	// return NaN
    168   1.1  mrg 	{
    169   1.1  mrg #ifdef SET_STATUS_FLAGS
    170   1.1  mrg 	  __set_status_flags (pfpsf, INVALID_EXCEPTION);
    171   1.1  mrg #endif
    172   1.1  mrg 	  res = NAN_MASK64;
    173   1.1  mrg 	  BID_RETURN (res);
    174   1.1  mrg 	}
    175   1.1  mrg       }
    176   1.1  mrg       // check if y is NaN
    177   1.1  mrg       if (((y & NAN_MASK64) == NAN_MASK64)) {
    178   1.1  mrg 	res = coefficient_y & QUIET_MASK64;
    179   1.1  mrg #ifdef SET_STATUS_FLAGS
    180   1.1  mrg 	if (((y & SNAN_MASK64) == SNAN_MASK64))
    181   1.1  mrg 	  __set_status_flags (pfpsf, INVALID_EXCEPTION);
    182   1.1  mrg #endif
    183   1.1  mrg 	BID_RETURN (res);
    184   1.1  mrg       }
    185   1.1  mrg       // otherwise return +/-Inf
    186   1.1  mrg       {
    187   1.1  mrg 	res = coefficient_x;
    188   1.1  mrg 	BID_RETURN (res);
    189   1.1  mrg       }
    190   1.1  mrg     }
    191   1.1  mrg     // x is 0
    192   1.1  mrg     {
    193   1.1  mrg       if (((y & INFINITY_MASK64) != INFINITY_MASK64) && coefficient_y) {
    194   1.1  mrg 	if (exponent_y <= exponent_x) {
    195   1.1  mrg 	  res = y;
    196   1.1  mrg 	  BID_RETURN (res);
    197   1.1  mrg 	}
    198   1.1  mrg       }
    199   1.1  mrg     }
    200   1.1  mrg 
    201   1.1  mrg   }
    202   1.1  mrg   if (!valid_y) {
    203   1.1  mrg     // y is Inf. or NaN?
    204   1.1  mrg     if (((y & INFINITY_MASK64) == INFINITY_MASK64)) {
    205   1.1  mrg #ifdef SET_STATUS_FLAGS
    206   1.1  mrg       if ((y & SNAN_MASK64) == SNAN_MASK64)	// sNaN
    207   1.1  mrg 	__set_status_flags (pfpsf, INVALID_EXCEPTION);
    208   1.1  mrg #endif
    209   1.1  mrg       res = coefficient_y & QUIET_MASK64;
    210   1.1  mrg       BID_RETURN (res);
    211   1.1  mrg     }
    212   1.1  mrg     // y is 0
    213   1.1  mrg     if (!coefficient_x) {	// x==0
    214   1.1  mrg       if (exponent_x <= exponent_y)
    215   1.1  mrg 	res = ((UINT64) exponent_x) << 53;
    216   1.1  mrg       else
    217   1.1  mrg 	res = ((UINT64) exponent_y) << 53;
    218   1.1  mrg       if (sign_x == sign_y)
    219   1.1  mrg 	res |= sign_x;
    220   1.1  mrg #ifndef IEEE_ROUND_NEAREST_TIES_AWAY
    221   1.1  mrg #ifndef IEEE_ROUND_NEAREST
    222   1.1  mrg       if (rnd_mode == ROUNDING_DOWN && sign_x != sign_y)
    223   1.1  mrg 	res |= 0x8000000000000000ull;
    224   1.1  mrg #endif
    225   1.1  mrg #endif
    226   1.1  mrg       BID_RETURN (res);
    227   1.1  mrg     } else if (exponent_y >= exponent_x) {
    228   1.1  mrg       res = x;
    229   1.1  mrg       BID_RETURN (res);
    230   1.1  mrg     }
    231   1.1  mrg   }
    232   1.1  mrg   // sort arguments by exponent
    233   1.1  mrg   if (exponent_x < exponent_y) {
    234   1.1  mrg     sign_a = sign_y;
    235   1.1  mrg     exponent_a = exponent_y;
    236   1.1  mrg     coefficient_a = coefficient_y;
    237   1.1  mrg     sign_b = sign_x;
    238   1.1  mrg     exponent_b = exponent_x;
    239   1.1  mrg     coefficient_b = coefficient_x;
    240   1.1  mrg   } else {
    241   1.1  mrg     sign_a = sign_x;
    242   1.1  mrg     exponent_a = exponent_x;
    243   1.1  mrg     coefficient_a = coefficient_x;
    244   1.1  mrg     sign_b = sign_y;
    245   1.1  mrg     exponent_b = exponent_y;
    246   1.1  mrg     coefficient_b = coefficient_y;
    247   1.1  mrg   }
    248   1.1  mrg 
    249   1.1  mrg   // exponent difference
    250   1.1  mrg   diff_dec_expon = exponent_a - exponent_b;
    251   1.1  mrg 
    252   1.1  mrg   /* get binary coefficients of x and y */
    253   1.1  mrg 
    254   1.1  mrg   //--- get number of bits in the coefficients of x and y ---
    255   1.1  mrg 
    256   1.1  mrg   // version 2 (original)
    257   1.1  mrg   tempx.d = (double) coefficient_a;
    258   1.1  mrg   bin_expon_ca = ((tempx.i & MASK_BINARY_EXPONENT) >> 52) - 0x3ff;
    259   1.1  mrg 
    260   1.1  mrg   if (diff_dec_expon > MAX_FORMAT_DIGITS) {
    261   1.1  mrg     // normalize a to a 16-digit coefficient
    262   1.1  mrg 
    263   1.1  mrg     scale_ca = estimate_decimal_digits[bin_expon_ca];
    264   1.1  mrg     if (coefficient_a >= power10_table_128[scale_ca].w[0])
    265   1.1  mrg       scale_ca++;
    266   1.1  mrg 
    267   1.1  mrg     scale_k = 16 - scale_ca;
    268   1.1  mrg 
    269   1.1  mrg     coefficient_a *= power10_table_128[scale_k].w[0];
    270   1.1  mrg 
    271   1.1  mrg     diff_dec_expon -= scale_k;
    272   1.1  mrg     exponent_a -= scale_k;
    273   1.1  mrg 
    274   1.1  mrg     /* get binary coefficients of x and y */
    275   1.1  mrg 
    276   1.1  mrg     //--- get number of bits in the coefficients of x and y ---
    277   1.1  mrg     tempx.d = (double) coefficient_a;
    278   1.1  mrg     bin_expon_ca = ((tempx.i & MASK_BINARY_EXPONENT) >> 52) - 0x3ff;
    279   1.1  mrg 
    280   1.1  mrg     if (diff_dec_expon > MAX_FORMAT_DIGITS) {
    281   1.1  mrg #ifdef SET_STATUS_FLAGS
    282   1.1  mrg       if (coefficient_b) {
    283   1.1  mrg 	__set_status_flags (pfpsf, INEXACT_EXCEPTION);
    284   1.1  mrg       }
    285   1.1  mrg #endif
    286   1.1  mrg 
    287   1.1  mrg #ifndef IEEE_ROUND_NEAREST_TIES_AWAY
    288   1.1  mrg #ifndef IEEE_ROUND_NEAREST
    289   1.1  mrg       if (((rnd_mode) & 3) && coefficient_b)	// not ROUNDING_TO_NEAREST
    290   1.1  mrg       {
    291   1.1  mrg 	switch (rnd_mode) {
    292   1.1  mrg 	case ROUNDING_DOWN:
    293   1.1  mrg 	  if (sign_b) {
    294   1.1  mrg 	    coefficient_a -= ((((SINT64) sign_a) >> 63) | 1);
    295   1.1  mrg 	    if (coefficient_a < 1000000000000000ull) {
    296   1.1  mrg 	      exponent_a--;
    297   1.1  mrg 	      coefficient_a = 9999999999999999ull;
    298   1.1  mrg 	    } else if (coefficient_a >= 10000000000000000ull) {
    299   1.1  mrg 	      exponent_a++;
    300   1.1  mrg 	      coefficient_a = 1000000000000000ull;
    301   1.1  mrg 	    }
    302   1.1  mrg 	  }
    303   1.1  mrg 	  break;
    304   1.1  mrg 	case ROUNDING_UP:
    305   1.1  mrg 	  if (!sign_b) {
    306   1.1  mrg 	    coefficient_a += ((((SINT64) sign_a) >> 63) | 1);
    307   1.1  mrg 	    if (coefficient_a < 1000000000000000ull) {
    308   1.1  mrg 	      exponent_a--;
    309   1.1  mrg 	      coefficient_a = 9999999999999999ull;
    310   1.1  mrg 	    } else if (coefficient_a >= 10000000000000000ull) {
    311   1.1  mrg 	      exponent_a++;
    312   1.1  mrg 	      coefficient_a = 1000000000000000ull;
    313   1.1  mrg 	    }
    314   1.1  mrg 	  }
    315   1.1  mrg 	  break;
    316   1.1  mrg 	default:	// RZ
    317   1.1  mrg 	  if (sign_a != sign_b) {
    318   1.1  mrg 	    coefficient_a--;
    319   1.1  mrg 	    if (coefficient_a < 1000000000000000ull) {
    320   1.1  mrg 	      exponent_a--;
    321   1.1  mrg 	      coefficient_a = 9999999999999999ull;
    322   1.1  mrg 	    }
    323   1.1  mrg 	  }
    324   1.1  mrg 	  break;
    325   1.1  mrg 	}
    326   1.1  mrg       } else
    327   1.1  mrg #endif
    328   1.1  mrg #endif
    329   1.1  mrg 	// check special case here
    330   1.1  mrg 	if ((coefficient_a == 1000000000000000ull)
    331   1.1  mrg 	    && (diff_dec_expon == MAX_FORMAT_DIGITS + 1)
    332   1.1  mrg 	    && (sign_a ^ sign_b)
    333   1.1  mrg 	    && (coefficient_b > 5000000000000000ull)) {
    334   1.1  mrg 	coefficient_a = 9999999999999999ull;
    335   1.1  mrg 	exponent_a--;
    336   1.1  mrg       }
    337   1.1  mrg 
    338   1.1  mrg       res =
    339   1.1  mrg 	fast_get_BID64_check_OF (sign_a, exponent_a, coefficient_a,
    340   1.1  mrg 				 rnd_mode, pfpsf);
    341   1.1  mrg       BID_RETURN (res);
    342   1.1  mrg     }
    343   1.1  mrg   }
    344   1.1  mrg   // test whether coefficient_a*10^(exponent_a-exponent_b)  may exceed 2^62
    345   1.1  mrg   if (bin_expon_ca + estimate_bin_expon[diff_dec_expon] < 60) {
    346   1.1  mrg     // coefficient_a*10^(exponent_a-exponent_b)<2^63
    347   1.1  mrg 
    348   1.1  mrg     // multiply by 10^(exponent_a-exponent_b)
    349   1.1  mrg     coefficient_a *= power10_table_128[diff_dec_expon].w[0];
    350   1.1  mrg 
    351   1.1  mrg     // sign mask
    352   1.1  mrg     sign_b = ((SINT64) sign_b) >> 63;
    353   1.1  mrg     // apply sign to coeff. of b
    354   1.1  mrg     coefficient_b = (coefficient_b + sign_b) ^ sign_b;
    355   1.1  mrg 
    356   1.1  mrg     // apply sign to coefficient a
    357   1.1  mrg     sign_a = ((SINT64) sign_a) >> 63;
    358   1.1  mrg     coefficient_a = (coefficient_a + sign_a) ^ sign_a;
    359   1.1  mrg 
    360   1.1  mrg     coefficient_a += coefficient_b;
    361   1.1  mrg     // get sign
    362   1.1  mrg     sign_s = ((SINT64) coefficient_a) >> 63;
    363   1.1  mrg     coefficient_a = (coefficient_a + sign_s) ^ sign_s;
    364   1.1  mrg     sign_s &= 0x8000000000000000ull;
    365   1.1  mrg 
    366   1.1  mrg     // coefficient_a < 10^16 ?
    367   1.1  mrg     if (coefficient_a < power10_table_128[MAX_FORMAT_DIGITS].w[0]) {
    368   1.1  mrg #ifndef IEEE_ROUND_NEAREST_TIES_AWAY
    369   1.1  mrg #ifndef IEEE_ROUND_NEAREST
    370   1.1  mrg       if (rnd_mode == ROUNDING_DOWN && (!coefficient_a)
    371   1.1  mrg 	  && sign_a != sign_b)
    372   1.1  mrg 	sign_s = 0x8000000000000000ull;
    373   1.1  mrg #endif
    374   1.1  mrg #endif
    375   1.1  mrg       res = very_fast_get_BID64 (sign_s, exponent_b, coefficient_a);
    376   1.1  mrg       BID_RETURN (res);
    377   1.1  mrg     }
    378   1.1  mrg     // otherwise rounding is necessary
    379   1.1  mrg 
    380   1.1  mrg     // already know coefficient_a<10^19
    381   1.1  mrg     // coefficient_a < 10^17 ?
    382   1.1  mrg     if (coefficient_a < power10_table_128[17].w[0])
    383   1.1  mrg       extra_digits = 1;
    384   1.1  mrg     else if (coefficient_a < power10_table_128[18].w[0])
    385   1.1  mrg       extra_digits = 2;
    386   1.1  mrg     else
    387   1.1  mrg       extra_digits = 3;
    388   1.1  mrg 
    389   1.1  mrg #ifndef IEEE_ROUND_NEAREST_TIES_AWAY
    390   1.1  mrg #ifndef IEEE_ROUND_NEAREST
    391   1.1  mrg     rmode = rnd_mode;
    392   1.1  mrg     if (sign_s && (unsigned) (rmode - 1) < 2)
    393   1.1  mrg       rmode = 3 - rmode;
    394   1.1  mrg #else
    395   1.1  mrg     rmode = 0;
    396   1.1  mrg #endif
    397   1.1  mrg #else
    398   1.1  mrg     rmode = 0;
    399   1.1  mrg #endif
    400   1.1  mrg     coefficient_a += round_const_table[rmode][extra_digits];
    401   1.1  mrg 
    402   1.1  mrg     // get P*(2^M[extra_digits])/10^extra_digits
    403   1.1  mrg     __mul_64x64_to_128 (CT, coefficient_a,
    404   1.1  mrg 			reciprocals10_64[extra_digits]);
    405   1.1  mrg 
    406   1.1  mrg     // now get P/10^extra_digits: shift C64 right by M[extra_digits]-128
    407   1.1  mrg     amount = short_recip_scale[extra_digits];
    408   1.1  mrg     C64 = CT.w[1] >> amount;
    409   1.1  mrg 
    410   1.1  mrg   } else {
    411   1.1  mrg     // coefficient_a*10^(exponent_a-exponent_b) is large
    412   1.1  mrg     sign_s = sign_a;
    413   1.1  mrg 
    414   1.1  mrg #ifndef IEEE_ROUND_NEAREST_TIES_AWAY
    415   1.1  mrg #ifndef IEEE_ROUND_NEAREST
    416   1.1  mrg     rmode = rnd_mode;
    417   1.1  mrg     if (sign_s && (unsigned) (rmode - 1) < 2)
    418   1.1  mrg       rmode = 3 - rmode;
    419   1.1  mrg #else
    420   1.1  mrg     rmode = 0;
    421   1.1  mrg #endif
    422   1.1  mrg #else
    423   1.1  mrg     rmode = 0;
    424   1.1  mrg #endif
    425   1.1  mrg 
    426   1.1  mrg     // check whether we can take faster path
    427   1.1  mrg     scale_ca = estimate_decimal_digits[bin_expon_ca];
    428   1.1  mrg 
    429   1.1  mrg     sign_ab = sign_a ^ sign_b;
    430   1.1  mrg     sign_ab = ((SINT64) sign_ab) >> 63;
    431   1.1  mrg 
    432   1.1  mrg     // T1 = 10^(16-diff_dec_expon)
    433   1.1  mrg     T1 = power10_table_128[16 - diff_dec_expon].w[0];
    434   1.1  mrg 
    435   1.1  mrg     // get number of digits in coefficient_a
    436   1.1  mrg     if (coefficient_a >= power10_table_128[scale_ca].w[0]) {
    437   1.1  mrg       scale_ca++;
    438   1.1  mrg     }
    439   1.1  mrg 
    440   1.1  mrg     scale_k = 16 - scale_ca;
    441   1.1  mrg 
    442   1.1  mrg     // addition
    443   1.1  mrg     saved_ca = coefficient_a - T1;
    444   1.1  mrg     coefficient_a =
    445   1.1  mrg       (SINT64) saved_ca *(SINT64) power10_table_128[scale_k].w[0];
    446   1.1  mrg     extra_digits = diff_dec_expon - scale_k;
    447   1.1  mrg 
    448   1.1  mrg     // apply sign
    449   1.1  mrg     saved_cb = (coefficient_b + sign_ab) ^ sign_ab;
    450   1.1  mrg     // add 10^16 and rounding constant
    451   1.1  mrg     coefficient_b =
    452   1.1  mrg       saved_cb + 10000000000000000ull +
    453   1.1  mrg       round_const_table[rmode][extra_digits];
    454   1.1  mrg 
    455   1.1  mrg     // get P*(2^M[extra_digits])/10^extra_digits
    456   1.1  mrg     __mul_64x64_to_128 (CT, coefficient_b,
    457   1.1  mrg 			reciprocals10_64[extra_digits]);
    458   1.1  mrg 
    459   1.1  mrg     // now get P/10^extra_digits: shift C64 right by M[extra_digits]-128
    460   1.1  mrg     amount = short_recip_scale[extra_digits];
    461   1.1  mrg     C0_64 = CT.w[1] >> amount;
    462   1.1  mrg 
    463   1.1  mrg     // result coefficient
    464   1.1  mrg     C64 = C0_64 + coefficient_a;
    465   1.1  mrg     // filter out difficult (corner) cases
    466   1.1  mrg     // this test ensures the number of digits in coefficient_a does not change
    467   1.1  mrg     // after adding (the appropriately scaled and rounded) coefficient_b
    468   1.1  mrg     if ((UINT64) (C64 - 1000000000000000ull - 1) >
    469   1.1  mrg 	9000000000000000ull - 2) {
    470   1.1  mrg       if (C64 >= 10000000000000000ull) {
    471   1.1  mrg 	// result has more than 16 digits
    472   1.1  mrg 	if (!scale_k) {
    473   1.1  mrg 	  // must divide coeff_a by 10
    474   1.1  mrg 	  saved_ca = saved_ca + T1;
    475   1.1  mrg 	  __mul_64x64_to_128 (CA, saved_ca, 0x3333333333333334ull);
    476   1.1  mrg 	  //reciprocals10_64[1]);
    477   1.1  mrg 	  coefficient_a = CA.w[1] >> 1;
    478   1.1  mrg 	  rem_a =
    479   1.1  mrg 	    saved_ca - (coefficient_a << 3) - (coefficient_a << 1);
    480   1.1  mrg 	  coefficient_a = coefficient_a - T1;
    481   1.1  mrg 
    482   1.1  mrg 	  saved_cb += rem_a * power10_table_128[diff_dec_expon].w[0];
    483   1.1  mrg 	} else
    484   1.1  mrg 	  coefficient_a =
    485   1.1  mrg 	    (SINT64) (saved_ca - T1 -
    486   1.1  mrg 		      (T1 << 3)) * (SINT64) power10_table_128[scale_k -
    487   1.1  mrg 							      1].w[0];
    488   1.1  mrg 
    489   1.1  mrg 	extra_digits++;
    490   1.1  mrg 	coefficient_b =
    491   1.1  mrg 	  saved_cb + 100000000000000000ull +
    492   1.1  mrg 	  round_const_table[rmode][extra_digits];
    493   1.1  mrg 
    494   1.1  mrg 	// get P*(2^M[extra_digits])/10^extra_digits
    495   1.1  mrg 	__mul_64x64_to_128 (CT, coefficient_b,
    496   1.1  mrg 			    reciprocals10_64[extra_digits]);
    497   1.1  mrg 
    498   1.1  mrg 	// now get P/10^extra_digits: shift C64 right by M[extra_digits]-128
    499   1.1  mrg 	amount = short_recip_scale[extra_digits];
    500   1.1  mrg 	C0_64 = CT.w[1] >> amount;
    501   1.1  mrg 
    502   1.1  mrg 	// result coefficient
    503   1.1  mrg 	C64 = C0_64 + coefficient_a;
    504   1.1  mrg       } else if (C64 <= 1000000000000000ull) {
    505   1.1  mrg 	// less than 16 digits in result
    506   1.1  mrg 	coefficient_a =
    507   1.1  mrg 	  (SINT64) saved_ca *(SINT64) power10_table_128[scale_k +
    508   1.1  mrg 							1].w[0];
    509   1.1  mrg 	//extra_digits --;
    510   1.1  mrg 	exponent_b--;
    511   1.1  mrg 	coefficient_b =
    512   1.1  mrg 	  (saved_cb << 3) + (saved_cb << 1) + 100000000000000000ull +
    513   1.1  mrg 	  round_const_table[rmode][extra_digits];
    514   1.1  mrg 
    515   1.1  mrg 	// get P*(2^M[extra_digits])/10^extra_digits
    516   1.1  mrg 	__mul_64x64_to_128 (CT_new, coefficient_b,
    517   1.1  mrg 			    reciprocals10_64[extra_digits]);
    518   1.1  mrg 
    519   1.1  mrg 	// now get P/10^extra_digits: shift C64 right by M[extra_digits]-128
    520   1.1  mrg 	amount = short_recip_scale[extra_digits];
    521   1.1  mrg 	C0_64 = CT_new.w[1] >> amount;
    522   1.1  mrg 
    523   1.1  mrg 	// result coefficient
    524   1.1  mrg 	C64_new = C0_64 + coefficient_a;
    525   1.1  mrg 	if (C64_new < 10000000000000000ull) {
    526   1.1  mrg 	  C64 = C64_new;
    527   1.1  mrg #ifdef SET_STATUS_FLAGS
    528   1.1  mrg 	  CT = CT_new;
    529   1.1  mrg #endif
    530   1.1  mrg 	} else
    531   1.1  mrg 	  exponent_b++;
    532   1.1  mrg       }
    533   1.1  mrg 
    534   1.1  mrg     }
    535   1.1  mrg 
    536   1.1  mrg   }
    537   1.1  mrg 
    538   1.1  mrg #ifndef IEEE_ROUND_NEAREST_TIES_AWAY
    539   1.1  mrg #ifndef IEEE_ROUND_NEAREST
    540   1.1  mrg   if (rmode == 0)	//ROUNDING_TO_NEAREST
    541   1.1  mrg #endif
    542   1.1  mrg     if (C64 & 1) {
    543   1.1  mrg       // check whether fractional part of initial_P/10^extra_digits is
    544   1.1  mrg       // exactly .5
    545   1.1  mrg       // this is the same as fractional part of
    546   1.1  mrg       //      (initial_P + 0.5*10^extra_digits)/10^extra_digits is exactly zero
    547   1.1  mrg 
    548   1.1  mrg       // get remainder
    549   1.1  mrg       remainder_h = CT.w[1] << (64 - amount);
    550   1.1  mrg 
    551   1.1  mrg       // test whether fractional part is 0
    552   1.1  mrg       if (!remainder_h && (CT.w[0] < reciprocals10_64[extra_digits])) {
    553   1.1  mrg 	C64--;
    554   1.1  mrg       }
    555   1.1  mrg     }
    556   1.1  mrg #endif
    557   1.1  mrg 
    558   1.1  mrg #ifdef SET_STATUS_FLAGS
    559   1.1  mrg   status = INEXACT_EXCEPTION;
    560   1.1  mrg 
    561   1.1  mrg   // get remainder
    562   1.1  mrg   remainder_h = CT.w[1] << (64 - amount);
    563   1.1  mrg 
    564   1.1  mrg   switch (rmode) {
    565   1.1  mrg   case ROUNDING_TO_NEAREST:
    566   1.1  mrg   case ROUNDING_TIES_AWAY:
    567   1.1  mrg     // test whether fractional part is 0
    568   1.1  mrg     if ((remainder_h == 0x8000000000000000ull)
    569   1.1  mrg 	&& (CT.w[0] < reciprocals10_64[extra_digits]))
    570   1.1  mrg       status = EXACT_STATUS;
    571   1.1  mrg     break;
    572   1.1  mrg   case ROUNDING_DOWN:
    573   1.1  mrg   case ROUNDING_TO_ZERO:
    574   1.1  mrg     if (!remainder_h && (CT.w[0] < reciprocals10_64[extra_digits]))
    575   1.1  mrg       status = EXACT_STATUS;
    576   1.1  mrg     //if(!C64 && rmode==ROUNDING_DOWN) sign_s=sign_y;
    577   1.1  mrg     break;
    578   1.1  mrg   default:
    579   1.1  mrg     // round up
    580   1.1  mrg     __add_carry_out (tmp, carry, CT.w[0],
    581   1.1  mrg 		     reciprocals10_64[extra_digits]);
    582   1.1  mrg     if ((remainder_h >> (64 - amount)) + carry >=
    583   1.1  mrg 	(((UINT64) 1) << amount))
    584   1.1  mrg       status = EXACT_STATUS;
    585   1.1  mrg     break;
    586   1.1  mrg   }
    587   1.1  mrg   __set_status_flags (pfpsf, status);
    588   1.1  mrg 
    589   1.1  mrg #endif
    590   1.1  mrg 
    591   1.1  mrg   res =
    592   1.1  mrg     fast_get_BID64_check_OF (sign_s, exponent_b + extra_digits, C64,
    593   1.1  mrg 			     rnd_mode, pfpsf);
    594   1.1  mrg   BID_RETURN (res);
    595   1.1  mrg }
    596