3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-04-08 10:25:18 +00:00

More implementation of fp.to_ieee_bv for unspecified input/output

Relates to #507
This commit is contained in:
Christoph M. Wintersteiger 2016-03-15 15:11:37 +00:00
parent a9df4a208f
commit 371573cbff
3 changed files with 40 additions and 19 deletions

View file

@ -2946,8 +2946,11 @@ void fpa2bv_converter::mk_to_ieee_bv(func_decl * f, unsigned num, expr * const *
expr_ref sig_unspec(s, m);
if (sbits > 2)
sig_unspec = m_bv_util.mk_concat(mk_to_ieee_bv_unspecified(sbits - 2),
m_bv_util.mk_numeral(1, 1));
sig_unspec = m_bv_util.mk_concat(
mk_to_ieee_bv_unspecified(sbits - 2),
m_bv_util.mk_numeral(1, 1));
else
sig_unspec = m_bv_util.mk_numeral(1, 1);
result = m_bv_util.mk_concat(m_bv_util.mk_concat(sgn, e), m.mk_ite(x_is_nan, sig_unspec, s));
}

View file

@ -158,8 +158,15 @@ br_status fpa_rewriter::mk_to_ieee_bv_unspecified(func_decl * f, expr_ref & resu
if (m_hi_fp_unspecified)
// The "hardware interpretation" is 0.
result = bu.mk_numeral(0, bv_sz);
else
result = m_util.mk_internal_to_ieee_bv_unspecified(bv_sz);
else {
unsigned sbits = m_util.get_sbits(f->get_domain()[0]);
if (sbits > 2)
result = bu.mk_concat(m_util.mk_internal_to_ieee_bv_unspecified(sbits - 2),
bu.mk_numeral(1, 1));
else
result = bu.mk_numeral(1, 1);
}
return BR_DONE;
}
@ -863,16 +870,17 @@ br_status fpa_rewriter::mk_to_ieee_bv(func_decl * f, expr * arg, expr_ref & resu
if (m_util.is_numeral(arg, v)) {
if (m_fm.is_nan(v) || m_fm.is_inf(v)) {
if (m_fm.is_nan(v)) {
mk_to_ieee_bv_unspecified(f, result);
return BR_REWRITE_FULL;
}
bv_util bu(m());
scoped_mpz rz(m_fm.mpq_manager());
m_fm.to_ieee_bv_mpz(v, rz);
result = bu.mk_numeral(rational(rz), v.get().get_ebits() + v.get().get_sbits());
return BR_DONE;
else {
bv_util bu(m());
scoped_mpz rz(m_fm.mpq_manager());
m_fm.to_ieee_bv_mpz(v, rz);
result = bu.mk_numeral(rational(rz), v.get().get_ebits() + v.get().get_sbits());
return BR_DONE;
}
}
return BR_FAILED;

View file

@ -1190,18 +1190,28 @@ void mpf_manager::to_sbv_mpq(mpf_rounding_mode rm, const mpf & x, scoped_mpq & o
}
void mpf_manager::to_ieee_bv_mpz(const mpf & x, scoped_mpz & o) {
SASSERT(!is_nan(x) && !is_inf(x));
SASSERT(!is_nan(x));
SASSERT(exp(x) < INT_MAX);
unsigned sbits = x.get_sbits();
unsigned ebits = x.get_ebits();
scoped_mpz biased_exp(m_mpz_manager);
m_mpz_manager.set(biased_exp, bias_exp(ebits, exp(x)));
m_mpz_manager.set(o, sgn(x));
m_mpz_manager.mul2k(o, ebits);
m_mpz_manager.add(o, biased_exp, o);
m_mpz_manager.mul2k(o, sbits - 1);
m_mpz_manager.add(o, sig(x), o);
if (is_inf(x)) {
m_mpz_manager.set(o, sgn(x));
m_mpz_manager.mul2k(o, ebits);
const mpz & exp = m_powers2.m1(ebits);
m_mpz_manager.add(o, exp, o);
m_mpz_manager.mul2k(o, sbits - 1);
}
else {
scoped_mpz biased_exp(m_mpz_manager);
m_mpz_manager.set(biased_exp, bias_exp(ebits, exp(x)));
m_mpz_manager.set(o, sgn(x));
m_mpz_manager.mul2k(o, ebits);
m_mpz_manager.add(o, biased_exp, o);
m_mpz_manager.mul2k(o, sbits - 1);
m_mpz_manager.add(o, sig(x), o);
}
}
void mpf_manager::rem(mpf const & x, mpf const & y, mpf & o) {