UINT64 bid64_fma (UINT64 x, UINT64 y, UINT64 z _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) { #endif UINT128 P, PU, CT, CZ; UINT64 sign_x, sign_y, coefficient_x, coefficient_y, sign_z, coefficient_z; UINT64 C64, remainder_y, res; UINT64 CYh, CY0L, T, valid_x, valid_y, valid_z; int_double tempx, tempy; int extra_digits, exponent_x, exponent_y, bin_expon_cx, bin_expon_cy, bin_expon_product, rmode; int digits_p, bp, final_exponent, exponent_z, digits_z, ez, ey, scale_z, uf_status; #if DECIMAL_CALL_BY_REFERENCE #if !DECIMAL_GLOBAL_ROUNDING _IDEC_round rnd_mode = *prnd_mode; #endif x = *px; y = *py; z = *pz; #endif valid_x = unpack_BID64 (&sign_x, &exponent_x, &coefficient_x, x); valid_y = unpack_BID64 (&sign_y, &exponent_y, &coefficient_y, y); valid_z = unpack_BID64 (&sign_z, &exponent_z, &coefficient_z, z); // unpack arguments, check for NaN, Infinity, or 0 if (!valid_x || !valid_y || !valid_z) { if ((y & MASK_NAN) == MASK_NAN) { // y is NAN // if x = {0, f, inf, NaN}, y = NaN, z = {0, f, inf, NaN} then res = Q (y) // check first for non-canonical NaN payload y = y & 0xfe03ffffffffffffull; // clear G6-G12 if ((y & 0x0003ffffffffffffull) > 999999999999999ull) { y = y & 0xfe00000000000000ull; // clear G6-G12 and the payload bits } if ((y & MASK_SNAN) == MASK_SNAN) { // y is SNAN // set invalid flag *pfpsf |= INVALID_EXCEPTION; // return quiet (y) res = y & 0xfdffffffffffffffull; } else { // y is QNaN // return y res = y; // if z = SNaN or x = SNaN signal invalid exception if ((z & MASK_SNAN) == MASK_SNAN || (x & MASK_SNAN) == MASK_SNAN) { // set invalid flag *pfpsf |= INVALID_EXCEPTION; } } BID_RETURN (res) } else if ((z & MASK_NAN) == MASK_NAN) { // z is NAN
BID_UINT64 bid64_logb (BID_UINT64 x _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) { #endif int ires, exponent_x; BID_UINT64 sign_x, coefficient_x; BID_UINT64 valid_x, res; valid_x = unpack_BID64 (&sign_x, &exponent_x, &coefficient_x, x); if (!valid_x) { // test if x is NaN/Inf if ((x & 0x7800000000000000ull) == 0x7800000000000000ull) { #ifdef BID_SET_STATUS_FLAGS if ((x & 0x7e00000000000000ull) == 0x7e00000000000000ull) // sNaN __set_status_flags (pfpsf, BID_INVALID_EXCEPTION); #endif res = (coefficient_x) & QUIET_MASK64; if ((x & 0x7c00000000000000ull) == 0x7800000000000000ull) res &= 0x7fffffffffffffffull; BID_RETURN (res); } // x is 0 #ifdef BID_SET_STATUS_FLAGS __set_status_flags (pfpsf, BID_ZERO_DIVIDE_EXCEPTION); #endif res = 0xf800000000000000ull; BID_RETURN (res); } BIDECIMAL_CALL1_NORND (bid64_ilogb, ires, x); if (ires & 0x80000000) res = 0xb1c0000000000000ull | (BID_UINT64)(-ires); else res = 0x31c0000000000000ull | (BID_UINT64)ires; BID_RETURN (res); }
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ******************************************************************************/ #include "bid_trans.h" BID_F80_CONST_DEF( c_half, 3ffe000000000000, 0000000000000000); // 0.5 BID_TYPE0_FUNCTION_ARGTYPE1(BID_UINT64, bid64_atanh, BID_UINT64, x) BID_UINT64 sign_x, coefficient_x, xn, tmp, y; BID_UINT64 valid_x, res, one, one_m_x; BID_F80_TYPE xq, rq; int exponent_x; valid_x = unpack_BID64 (&sign_x, &exponent_x, &coefficient_x, x); if (!valid_x) { // test if x is NaN if ((x & 0x7c00000000000000ull) == 0x7c00000000000000ull) { #ifdef BID_SET_STATUS_FLAGS if ((x & 0x7e00000000000000ull) == 0x7e00000000000000ull) // sNaN __set_status_flags (pfpsf, BID_INVALID_EXCEPTION); #endif res = (coefficient_x) & QUIET_MASK64; BID_RETURN (res); } // x is Infinity? if ((x & 0x7800000000000000ull) == 0x7800000000000000ull) { #ifdef BID_SET_STATUS_FLAGS __set_status_flags (pfpsf, BID_INVALID_EXCEPTION);
UINT64 bid64_scalb (UINT64 x, int n _RND_MODE_PARAM _EXC_FLAGS_PARAM _EXC_MASKS_PARAM _EXC_INFO_PARAM) { #endif UINT64 sign_x, coefficient_x, res; SINT64 exp64; int exponent_x, rmode; #if DECIMAL_CALL_BY_REFERENCE #if !DECIMAL_GLOBAL_ROUNDING _IDEC_round rnd_mode = *prnd_mode; #endif x = *px; n = *pn; #endif // unpack arguments, check for NaN or Infinity if (!unpack_BID64 (&sign_x, &exponent_x, &coefficient_x, x)) { // x is Inf. or NaN or 0 #ifdef SET_STATUS_FLAGS if ((x & SNAN_MASK64) == SNAN_MASK64) // y is sNaN __set_status_flags (pfpsf, INVALID_EXCEPTION); #endif if (coefficient_x) res = coefficient_x & QUIET_MASK64; else { exp64 = (SINT64) exponent_x + (SINT64) n; if(exp64<0) exp64=0; if(exp64>MAX_DECIMAL_EXPONENT) exp64=MAX_DECIMAL_EXPONENT; exponent_x = exp64; res = very_fast_get_BID64 (sign_x, exponent_x, coefficient_x); // 0 } BID_RETURN (res); } exp64 = (SINT64) exponent_x + (SINT64) n; exponent_x = exp64; if ((UINT32) exponent_x <= MAX_DECIMAL_EXPONENT) { res = very_fast_get_BID64 (sign_x, exponent_x, coefficient_x); BID_RETURN (res); } // check for overflow if (exp64 > MAX_DECIMAL_EXPONENT) { // try to normalize coefficient while ((coefficient_x < 1000000000000000ull) && (exp64 > MAX_DECIMAL_EXPONENT)) { // coefficient_x < 10^15, scale by 10 coefficient_x = (coefficient_x << 1) + (coefficient_x << 3); exponent_x--; exp64--; } if (exp64 <= MAX_DECIMAL_EXPONENT) { res = very_fast_get_BID64 (sign_x, exponent_x, coefficient_x); BID_RETURN (res); } else exponent_x = 0x7fffffff; // overflow } // exponent < 0 // the BID pack routine will round the coefficient rmode = rnd_mode; res = get_BID64 (sign_x, exponent_x, coefficient_x, rmode, pfpsf); BID_RETURN (res); }