mirror of
https://github.com/Z3Prover/z3
synced 2026-07-15 03:25:43 +00:00
refactor: address code review feedback for transcendental decimal formatting
This commit is contained in:
parent
657c575dbf
commit
be243ba2bd
1 changed files with 18 additions and 4 deletions
|
|
@ -746,19 +746,23 @@ class smt2_printer {
|
||||||
format * format_transcendental_decimal(long double abs_val, bool is_neg) {
|
format * format_transcendental_decimal(long double abs_val, bool is_neg) {
|
||||||
long double int_part_ld;
|
long double int_part_ld;
|
||||||
long double frac = std::modf(abs_val, &int_part_ld);
|
long double frac = std::modf(abs_val, &int_part_ld);
|
||||||
if (frac < 0) frac = 0;
|
// abs_val is guaranteed non-negative by the caller, so frac >= 0.
|
||||||
|
|
||||||
std::ostringstream buffer;
|
std::ostringstream buffer;
|
||||||
|
// int_part_ld fits in unsigned long long for all mathematical constants
|
||||||
|
// and typical model values (e.g. pi~3, e~2, trig results in [-1,1]).
|
||||||
buffer << static_cast<unsigned long long>(int_part_ld) << ".";
|
buffer << static_cast<unsigned long long>(int_part_ld) << ".";
|
||||||
|
|
||||||
// Extract digits by truncation (consistent with mpq_manager::display_decimal)
|
// Extract digits by truncation (consistent with mpq_manager::display_decimal).
|
||||||
|
// Floating-point accumulation during digit extraction can push frac slightly
|
||||||
|
// below 0 or push a digit above 9; clamp both to stay well-formed.
|
||||||
for (unsigned i = 0; i < m_pp_decimal_precision; i++) {
|
for (unsigned i = 0; i < m_pp_decimal_precision; i++) {
|
||||||
frac *= 10.0L;
|
frac *= 10.0L;
|
||||||
unsigned digit = static_cast<unsigned>(frac);
|
unsigned digit = static_cast<unsigned>(frac);
|
||||||
if (digit > 9) digit = 9;
|
if (digit > 9) digit = 9; // guard against accumulated rounding error
|
||||||
buffer << digit;
|
buffer << digit;
|
||||||
frac -= static_cast<long double>(digit);
|
frac -= static_cast<long double>(digit);
|
||||||
if (frac < 0) frac = 0;
|
frac = std::max(0.0L, frac); // guard against accumulated rounding error
|
||||||
}
|
}
|
||||||
buffer << "?";
|
buffer << "?";
|
||||||
format * f = mk_string(m(), buffer.str());
|
format * f = mk_string(m(), buffer.str());
|
||||||
|
|
@ -795,6 +799,8 @@ class smt2_printer {
|
||||||
// and irrational algebraic numerals)
|
// and irrational algebraic numerals)
|
||||||
long double darg;
|
long double darg;
|
||||||
if (autil.is_numeral(arg, rval, is_int)) {
|
if (autil.is_numeral(arg, rval, is_int)) {
|
||||||
|
// rational::get_double() returns double; cast to long double for
|
||||||
|
// trig computation (sufficient for pp.decimal_precision <= 15).
|
||||||
darg = static_cast<long double>(rval.get_double());
|
darg = static_cast<long double>(rval.get_double());
|
||||||
}
|
}
|
||||||
else if (autil.is_uminus(arg) &&
|
else if (autil.is_uminus(arg) &&
|
||||||
|
|
@ -806,6 +812,8 @@ class smt2_printer {
|
||||||
algebraic_numbers::manager & am = autil.am();
|
algebraic_numbers::manager & am = autil.am();
|
||||||
rational lo;
|
rational lo;
|
||||||
am.get_lower(aval, lo, m_pp_decimal_precision + 2);
|
am.get_lower(aval, lo, m_pp_decimal_precision + 2);
|
||||||
|
// rational::get_double() returns double; precision is adequate for
|
||||||
|
// typical pp.decimal_precision values.
|
||||||
darg = static_cast<long double>(lo.get_double());
|
darg = static_cast<long double>(lo.get_double());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
@ -873,6 +881,8 @@ class smt2_printer {
|
||||||
rational rval;
|
rational rval;
|
||||||
bool is_int;
|
bool is_int;
|
||||||
if (autil.is_numeral(t, rval, is_int)) {
|
if (autil.is_numeral(t, rval, is_int)) {
|
||||||
|
// rational::get_double() → double cast; adequate for typical
|
||||||
|
// pp.decimal_precision values (default 10, max ~15 significant digits).
|
||||||
result = static_cast<long double>(rval.get_double());
|
result = static_cast<long double>(rval.get_double());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -883,6 +893,8 @@ class smt2_printer {
|
||||||
algebraic_numbers::manager & am = autil.am();
|
algebraic_numbers::manager & am = autil.am();
|
||||||
rational lo;
|
rational lo;
|
||||||
am.get_lower(aval, lo, m_pp_decimal_precision + 2);
|
am.get_lower(aval, lo, m_pp_decimal_precision + 2);
|
||||||
|
// rational::get_double() → double cast; adequate for typical
|
||||||
|
// pp.decimal_precision values.
|
||||||
result = static_cast<long double>(lo.get_double());
|
result = static_cast<long double>(lo.get_double());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
@ -984,6 +996,8 @@ class smt2_printer {
|
||||||
bool l_trans = false, r_trans = false;
|
bool l_trans = false, r_trans = false;
|
||||||
if (!try_eval_as_long_double(t->get_arg(0), lhs, l_trans)) return false;
|
if (!try_eval_as_long_double(t->get_arg(0), lhs, l_trans)) return false;
|
||||||
if (!try_eval_as_long_double(t->get_arg(1), rhs, r_trans)) return false;
|
if (!try_eval_as_long_double(t->get_arg(1), rhs, r_trans)) return false;
|
||||||
|
// Exact-zero comparison is safe: rational and algebraic numerals
|
||||||
|
// can only produce exactly 0.0L here if the value is exactly zero.
|
||||||
if (rhs == 0.0L) return false;
|
if (rhs == 0.0L) return false;
|
||||||
any_trans = l_trans || r_trans;
|
any_trans = l_trans || r_trans;
|
||||||
if (!any_trans) return false;
|
if (!any_trans) return false;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue