3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-23 17:15:31 +00:00
This commit is contained in:
Nikolaj Bjorner 2017-07-31 13:24:57 -07:00
commit 063b6e9ea5
9 changed files with 139 additions and 103 deletions

View file

@ -840,16 +840,19 @@ void mpf_manager::fma(mpf_rounding_mode rm, mpf const & x, mpf const & y, mpf co
SASSERT(m_mpz_manager.lt(mr.significand(), m_powers2(2*x.sbits)));
SASSERT(m_mpz_manager.ge(mr.significand(), m_powers2(2*x.sbits - 2)));
// Introduce extra bits into c in _[0].[sbits-1] s.t. c in _[0].[2*sbits-2]
c.set(x.ebits+2, 2*x.sbits-1, c.sign(), c.exponent(), c.significand());
m_mpz_manager.mul2k(c.significand(), x.sbits - 1);
// Introduce (sbits+3) extra bits into c in _[0].[sbits-1] s.t. c in _[0].[2*sbits-2]
c.set(x.ebits+2, 2*x.sbits-1+3, c.sign(), c.exponent(), c.significand());
m_mpz_manager.mul2k(c.significand(), x.sbits - 1 + 3);
// And + 3 bits into mr as well.
mr.set(x.ebits + 2, 2 * x.sbits - 1 + 3, mr.sign(), mr.exponent(), mr.significand());
m_mpz_manager.mul2k(mr.significand(), 3);
TRACE("mpf_dbg", tout << "C_= " << to_string(c) << std::endl;
tout << "C_= " << to_string_binary(c, 1, 0) << std::endl;);
SASSERT(m_mpz_manager.lt(c.significand(), m_powers2(2*x.sbits)));
SASSERT(m_mpz_manager.lt(c.significand(), m_powers2(2*x.sbits + 3)));
SASSERT(m_mpz_manager.is_zero(c.significand()) ||
m_mpz_manager.ge(c.significand(), m_powers2(2*x.sbits - 2)));
m_mpz_manager.ge(c.significand(), m_powers2(2*x.sbits - 2 + 3)));
if (exp(c) > exp(mr)) {
TRACE("mpf_dbg", tout << "Swap!" << std::endl;);
@ -860,8 +863,8 @@ void mpf_manager::fma(mpf_rounding_mode rm, mpf const & x, mpf const & y, mpf co
mpf_exp_t exp_delta_w = exp(mr) - exp(c);
SASSERT(exp(mr) >= exp(c) && exp_delta_w >= 0);
if (exp_delta_w > 2 * x.sbits)
exp_delta_w = 2 * x.sbits;
if (exp_delta_w > 2 * x.sbits + 3)
exp_delta_w = 2 * x.sbits + 3;
unsigned exp_delta = (unsigned)exp_delta_w;
@ -905,8 +908,8 @@ void mpf_manager::fma(mpf_rounding_mode rm, mpf const & x, mpf const & y, mpf co
// Renormalize
bool renorm_sticky = false;
SASSERT(m_mpz_manager.lt(res.significand(), m_powers2(2 * x.sbits + 1)));
if (m_mpz_manager.ge(res.significand(), m_powers2(2 * x.sbits)))
SASSERT(m_mpz_manager.lt(res.significand(), m_powers2(2 * x.sbits + 1 + 3)));
if (m_mpz_manager.ge(res.significand(), m_powers2(2 * x.sbits + 3)))
{
SASSERT(exp(res) < mk_max_exp(x.ebits)); // NYI.
@ -919,7 +922,7 @@ void mpf_manager::fma(mpf_rounding_mode rm, mpf const & x, mpf const & y, mpf co
mpf_exp_t min_exp = mk_min_exp(x.ebits);
unsigned sig_width = m_mpz_manager.prev_power_of_two(res.get().significand) + 1;
mpf_exp_t sig_lz = 2 * x.sbits - sig_width;
mpf_exp_t sig_lz = 2 * x.sbits + 3 - sig_width;
mpf_exp_t max_exp_delta = res.exponent() - min_exp;
unsigned renorm_delta = (unsigned) std::max((mpf_exp_t)0, std::min(sig_lz, max_exp_delta));
res.get().exponent -= renorm_delta;
@ -930,11 +933,11 @@ void mpf_manager::fma(mpf_rounding_mode rm, mpf const & x, mpf const & y, mpf co
set(o, x.ebits, x.sbits, res.sign(), res.exponent(), mpz(0));
if (x.sbits >= 4) {
m_mpz_manager.machine_div_rem(res.significand(), m_powers2(x.sbits - 4), o.significand, sticky_rem);
m_mpz_manager.machine_div_rem(res.significand(), m_powers2(x.sbits - 4 + 3), o.significand, sticky_rem);
renorm_sticky |= !m_mpz_manager.is_zero(sticky_rem);
}
else {
m_mpz_manager.mul2k(res.significand(), 4 - x.sbits, o.significand);
m_mpz_manager.mul2k(res.significand(), 4 - x.sbits + 3, o.significand);
}
if (renorm_sticky && m_mpz_manager.is_even(o.significand))

View file

@ -50,6 +50,7 @@ public:
inc_ref();
}
ref (ref && r): m_ptr (r.detach ()) {}
~ref() {
dec_ref();
}
@ -89,6 +90,14 @@ public:
return *this;
}
ref & operator=(ref &&r) {
if (this != &r) {
dec_ref ();
m_ptr = r.detach ();
}
return *this;
}
void reset() {
dec_ref();
m_ptr = 0;
@ -107,6 +116,11 @@ public:
friend bool operator!=(const ref & r1, const ref & r2) {
return r1.m_ptr != r2.m_ptr;
}
friend void swap (ref &r1, ref &r2) {
T* tmp = r1.m_ptr;
r1.m_ptr = r2.m_ptr;
r2.m_ptr = tmp;
}
};
/**