3
0
Fork 0
mirror of https://github.com/Z3Prover/z3 synced 2025-07-27 06:27:56 +00:00

avoid rationals for addition in checked_int64

Signed-off-by: Nikolaj Bjorner <nbjorner@microsoft.com>
This commit is contained in:
Nikolaj Bjorner 2017-11-19 20:41:42 -08:00
parent 07031798ec
commit 620bd81269

View file

@ -116,59 +116,49 @@ public:
const checked_int64 operator--(int) { checked_int64 tmp(*this); --(*this); return tmp; } const checked_int64 operator--(int) { checked_int64 tmp(*this); --(*this); return tmp; }
checked_int64& operator+=(checked_int64 const& other) { checked_int64& operator+=(checked_int64 const& other) {
if (CHECK && m_value > 0 && other.m_value > 0 && if (CHECK) {
(m_value > INT_MAX || other.m_value > INT_MAX)) { uint64 x = static_cast<uint64>(m_value);
rational r(r64(m_value) + r64(other.m_value)); uint64 y = static_cast<uint64>(other.m_value);
if (!r.is_int64()) { int64 r = static_cast<int64>(x + y);
throw overflow_exception(); if (m_value > 0 && other.m_value > 0 && r <= 0) throw overflow_exception();
} if (m_value < 0 && other.m_value < 0 && r >= 0) throw overflow_exception();
m_value = r.get_int64(); m_value = r;
return *this;
}
if (CHECK && m_value < 0 && other.m_value < 0 &&
(m_value < INT_MIN || other.m_value < INT_MIN)) {
rational r(r64(m_value) + r64(other.m_value));
if (!r.is_int64()) {
throw overflow_exception();
}
m_value = r.get_int64();
return *this;
} }
else {
m_value += other.m_value; m_value += other.m_value;
}
return *this; return *this;
} }
checked_int64& operator-=(checked_int64 const& other) { checked_int64& operator-=(checked_int64 const& other) {
if (CHECK && m_value > 0 && other.m_value < 0 && if (CHECK) {
(m_value > INT_MAX || other.m_value < INT_MIN)) { uint64 x = static_cast<uint64>(m_value);
rational r(r64(m_value) - r64(other.m_value)); uint64 y = static_cast<uint64>(other.m_value);
if (!r.is_int64()) { int64 r = static_cast<int64>(x - y);
throw overflow_exception(); if (m_value > 0 && other.m_value < 0 && r <= 0) throw overflow_exception();
} if (m_value < 0 && other.m_value > 0 && r >= 0) throw overflow_exception();
m_value = r.get_int64(); m_value = r;
return *this;
}
if (CHECK && m_value < 0 && other.m_value > 0 &&
(m_value < INT_MIN || other.m_value > INT_MAX)) {
rational r(r64(m_value) - r64(other.m_value));
if (!r.is_int64()) {
throw overflow_exception();
}
m_value = r.get_int64();
return *this;
} }
else {
m_value -= other.m_value; m_value -= other.m_value;
}
return *this; return *this;
} }
checked_int64& operator*=(checked_int64 const& other) { checked_int64& operator*=(checked_int64 const& other) {
if (CHECK) { if (CHECK) {
if (INT_MIN < m_value && m_value <= INT_MAX && INT_MIN < other.m_value && other.m_value <= INT_MAX) {
m_value *= other.m_value;
}
// TBD: could be tuned by using known techniques or 128-bit arithmetic.
else {
rational r(r64(m_value) * r64(other.m_value)); rational r(r64(m_value) * r64(other.m_value));
if (!r.is_int64()) { if (!r.is_int64()) {
throw overflow_exception(); throw overflow_exception();
} }
m_value = r.get_int64(); m_value = r.get_int64();
} }
}
else { else {
m_value *= other.m_value; m_value *= other.m_value;
} }