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