diff --git a/src/ast/fpa/fpa2bv_converter.cpp b/src/ast/fpa/fpa2bv_converter.cpp index 9ecac1ec9..b4c346170 100644 --- a/src/ast/fpa/fpa2bv_converter.cpp +++ b/src/ast/fpa/fpa2bv_converter.cpp @@ -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)); } diff --git a/src/ast/rewriter/fpa_rewriter.cpp b/src/ast/rewriter/fpa_rewriter.cpp index 8352e14ce..5d9175259 100644 --- a/src/ast/rewriter/fpa_rewriter.cpp +++ b/src/ast/rewriter/fpa_rewriter.cpp @@ -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; diff --git a/src/util/mpf.cpp b/src/util/mpf.cpp index 1d7ed1bb3..5de4c406a 100644 --- a/src/util/mpf.cpp +++ b/src/util/mpf.cpp @@ -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) {