mirror of
https://github.com/Z3Prover/z3
synced 2025-06-06 06:03:23 +00:00
parent
372bb4b25a
commit
eadf755628
2 changed files with 38 additions and 36 deletions
|
@ -1142,9 +1142,9 @@ void fpa2bv_converter::mk_rem(sort * s, expr_ref & x, expr_ref & y, expr_ref & r
|
|||
dbg_decouple("fpa2bv_rem_exp_diff", exp_diff);
|
||||
|
||||
// CMW: This creates _huge_ bit-vectors, which is potentially sub-optimal,
|
||||
// but calculating this via rem = x - y * nearest(x/y) creates huge
|
||||
// circuits, too. Lazy instantiation seems the way to go in the long run
|
||||
// (using the lazy bit-blaster helps on simple instances).
|
||||
// but calculating this via successive approx. of rem = x - y * nearest(x/y)
|
||||
// as in mpf::rem creates huge circuits, too. Lazy instantiation seems the
|
||||
// way to go in the long run (using the lazy bit-blaster helps on simple instances).
|
||||
expr_ref lshift(m), rshift(m), shifted(m), huge_rem(m), huge_div(m), huge_div_is_even(m);
|
||||
expr_ref a_sig_ext_l = a_sig, b_sig_ext_l = b_sig;
|
||||
scoped_mpz remaining(m_mpz_manager);
|
||||
|
@ -1170,14 +1170,8 @@ void fpa2bv_converter::mk_rem(sort * s, expr_ref & x, expr_ref & y, expr_ref & r
|
|||
m_mpz_manager.add(max_exp_diff_adj, 1, max_exp_diff_adj);
|
||||
expr_ref edr_tmp = exp_diff, nedr_tmp = neg_exp_diff;
|
||||
m_mpz_manager.set(remaining, max_exp_diff_adj);
|
||||
while (m_mpz_manager.gt(remaining, INT32_MAX)) {
|
||||
throw default_exception("zero extension overflow floating point types are too large");
|
||||
#if 0
|
||||
edr_tmp = m_bv_util.mk_zero_extend(INT32_MAX, edr_tmp);
|
||||
nedr_tmp = m_bv_util.mk_zero_extend(INT32_MAX, nedr_tmp);
|
||||
m_mpz_manager.sub(remaining, INT32_MAX, remaining);
|
||||
#endif
|
||||
}
|
||||
if (m_mpz_manager.gt(remaining, INT32_MAX))
|
||||
throw default_exception("zero extension bit-vector types are too large; would exhaust memory");
|
||||
if (!m_mpz_manager.is_zero(remaining)) {
|
||||
edr_tmp = m_bv_util.mk_zero_extend(m_mpz_manager.get_uint(remaining), edr_tmp);
|
||||
nedr_tmp = m_bv_util.mk_zero_extend(m_mpz_manager.get_uint(remaining), nedr_tmp);
|
||||
|
@ -1203,8 +1197,10 @@ void fpa2bv_converter::mk_rem(sort * s, expr_ref & x, expr_ref & y, expr_ref & r
|
|||
rndd_sig = m_bv_util.mk_extract(sbits+3, 0, huge_rem);
|
||||
rne_bv = m_bv_util.mk_numeral(BV_RM_TIES_TO_EVEN, 3);
|
||||
mk_leading_zeros(rndd_sig, ebits+2, rndd_sig_lz);
|
||||
dbg_decouple("fpa2bv_rem_rndd_sgn", rndd_sgn);
|
||||
dbg_decouple("fpa2bv_rem_rndd_sig", rndd_sig);
|
||||
dbg_decouple("fpa2bv_rem_rndd_sig_lz", rndd_sig_lz);
|
||||
dbg_decouple("fpa2bv_rem_rndd_exp", rndd_exp);
|
||||
|
||||
SASSERT(m_bv_util.get_bv_size(rndd_exp) == ebits+2);
|
||||
SASSERT(m_bv_util.get_bv_size(y_exp_m1) == ebits);
|
||||
|
@ -1222,16 +1218,22 @@ void fpa2bv_converter::mk_rem(sort * s, expr_ref & x, expr_ref & y, expr_ref & r
|
|||
dbg_decouple("fpa2bv_rem_y_sig_le_rndd_sig", y_sig_le_rndd_sig);
|
||||
dbg_decouple("fpa2bv_rem_y_sig_eq_rndd_sig", y_sig_eq_rndd_sig);
|
||||
|
||||
expr_ref sub_cnd(m);
|
||||
sub_cnd = m.mk_or(m.mk_and(rndd_exp_eq_y_exp, y_sig_le_rndd_sig),
|
||||
expr_ref adj_cnd(m);
|
||||
adj_cnd = m.mk_or(m.mk_and(rndd_exp_eq_y_exp, y_sig_le_rndd_sig),
|
||||
m.mk_and(rndd_exp_eq_y_exp_m1, y_sig_le_rndd_sig, m.mk_not(y_sig_eq_rndd_sig)),
|
||||
m.mk_and(rndd_exp_eq_y_exp_m1, y_sig_eq_rndd_sig, m.mk_not(huge_div_is_even)));
|
||||
dbg_decouple("fpa2bv_rem_sub_cnd", sub_cnd);
|
||||
dbg_decouple("fpa2bv_rem_adj_cnd", adj_cnd);
|
||||
|
||||
expr_ref rndd(m), rounded_sub_y(m), rounded_add_y(m);
|
||||
expr_ref rndd(m), rounded_sub_y(m), rounded_add_y(m), add_cnd(m), adjusted(m);
|
||||
round(s, rne_bv, rndd_sgn, rndd_sig, rndd_exp, rndd);
|
||||
mk_sub(s, rne_bv, rndd, y, rounded_sub_y);
|
||||
mk_ite(sub_cnd, rounded_sub_y, rndd, v7);
|
||||
mk_add(s, rne_bv, rndd, y, rounded_add_y);
|
||||
add_cnd = m.mk_not(m.mk_eq(rndd_sgn, b_sgn));
|
||||
mk_ite(add_cnd, rounded_add_y, rounded_sub_y, adjusted);
|
||||
mk_ite(adj_cnd, adjusted, rndd, v7);
|
||||
dbg_decouple("fpa2bv_rem_add_cnd", add_cnd);
|
||||
dbg_decouple("fpa2bv_rem_adj_cnd", adj_cnd);
|
||||
dbg_decouple("fpa2bv_rem_rndd", rndd);
|
||||
|
||||
// And finally, we tie them together.
|
||||
mk_ite(c6, v6, v7, result);
|
||||
|
|
|
@ -1309,7 +1309,7 @@ void mpf_manager::partial_remainder(mpf & x, mpf const & y, mpf_exp_t const & ex
|
|||
bool Q_sgn = x_div_y_sgn;
|
||||
mpf_exp_t Q_exp = x_div_y_exp;
|
||||
scoped_mpz Q_sig(m_mpz_manager), Q_rem(m_mpz_manager);
|
||||
unsigned Q_shft = (sbits-1) + (sbits+3) - (unsigned) (partial ? N :Q_exp);
|
||||
unsigned Q_shft = (sbits-1) + (sbits+3) - (unsigned) (partial ? N : Q_exp);
|
||||
if (partial) {
|
||||
// Round according to MPF_ROUND_TOWARD_ZERO
|
||||
SASSERT(0 < N && N < Q_exp && Q_exp < INT_MAX);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue