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); }
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); }