Changeset View
Changeset View
Standalone View
Standalone View
src/test/intmath_tests.cpp
Show First 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | const static std::vector<int64_t> INTERESTING_63_BIT_NUMBERS({ | ||||
0x7fff'ffff'ffff'ffff, | 0x7fff'ffff'ffff'ffff, | ||||
-0x7fff'ffff'ffff'ffff, | -0x7fff'ffff'ffff'ffff, | ||||
}); | }); | ||||
bool IsInScriptBounds(const i128_t &num_int) { | bool IsInScriptBounds(const i128_t &num_int) { | ||||
return num_int >= MIN_SCRIPT_63_BIT_INT && num_int <= MAX_SCRIPT_63_BIT_INT; | return num_int >= MIN_SCRIPT_63_BIT_INT && num_int <= MAX_SCRIPT_63_BIT_INT; | ||||
} | } | ||||
void CheckArithmeticResult(std::string operation_str, bool expect_overflow, | |||||
bool had_overflow, int64_t result, | |||||
i128_t expected_result) { | |||||
if (expect_overflow) { | |||||
BOOST_CHECK_MESSAGE(had_overflow, | |||||
strprintf("%s didn't overflow", operation_str)); | |||||
} else { | |||||
BOOST_CHECK_MESSAGE(!had_overflow, | |||||
strprintf("%s overflowed", operation_str)); | |||||
BOOST_CHECK_EQUAL(result, expected_result); | |||||
} | |||||
} | |||||
void CheckArithmetic(const int64_t a_64, const int64_t b_64) { | void CheckArithmetic(const int64_t a_64, const int64_t b_64) { | ||||
const i128_t a = a_64; | const i128_t a = a_64; | ||||
const i128_t b = b_64; | const i128_t b = b_64; | ||||
{ | { | ||||
bool expect_overflow = !IsInScriptBounds(a + b); | |||||
// Test AddInt63OverflowEmulated | // Test AddInt63OverflowEmulated | ||||
int64_t result_emulated; | |||||
bool had_overflow_emulated = | |||||
AddInt63OverflowEmulated(a_64, b_64, result_emulated); | |||||
CheckArithmeticResult(strprintf("%d + %d", a, b), expect_overflow, | |||||
had_overflow_emulated, result_emulated, a + b); | |||||
// Test AddInt63Overflow | |||||
int64_t result; | int64_t result; | ||||
bool expect_overflow = !IsInScriptBounds(a + b); | bool had_overflow = AddInt63Overflow(a_64, b_64, result); | ||||
bool had_overflow = AddInt63OverflowEmulated(a_64, b_64, result); | CheckArithmeticResult(strprintf("%d + %d", a, b), expect_overflow, | ||||
if (expect_overflow) { | had_overflow_emulated, result_emulated, a + b); | ||||
BOOST_CHECK_MESSAGE( | if (!expect_overflow) { | ||||
had_overflow, strprintf("%d + %d didn't overflow", a_64, b_64)); | BOOST_CHECK_EQUAL(result, result_emulated); | ||||
} else { | |||||
BOOST_CHECK_MESSAGE(!had_overflow, | |||||
strprintf("%d + %d overflowed", a_64, b_64)); | |||||
BOOST_CHECK_EQUAL(result, a + b); | |||||
} | } | ||||
BOOST_CHECK_EQUAL(had_overflow, had_overflow_emulated); | |||||
} | } | ||||
{ | { | ||||
// Test SubInt63OverflowEmulated | |||||
int64_t result; | |||||
bool expect_overflow = !IsInScriptBounds(a - b); | bool expect_overflow = !IsInScriptBounds(a - b); | ||||
bool had_overflow = SubInt63OverflowEmulated(a_64, b_64, result); | // Test AddInt63OverflowEmulated | ||||
if (expect_overflow) { | int64_t result_emulated; | ||||
BOOST_CHECK_MESSAGE( | bool had_overflow_emulated = | ||||
had_overflow, strprintf("%d - %d didn't overflow", a_64, b_64)); | SubInt63OverflowEmulated(a_64, b_64, result_emulated); | ||||
} else { | CheckArithmeticResult(strprintf("%d - %d", a, b), expect_overflow, | ||||
BOOST_CHECK_MESSAGE(!had_overflow, | had_overflow_emulated, result_emulated, a - b); | ||||
strprintf("%d - %d overflowed", a_64, b_64)); | // Test AddInt63Overflow | ||||
BOOST_CHECK_EQUAL(result, a - b); | int64_t result; | ||||
bool had_overflow = SubInt63Overflow(a_64, b_64, result); | |||||
CheckArithmeticResult(strprintf("%d - %d", a, b), expect_overflow, | |||||
had_overflow_emulated, result_emulated, a - b); | |||||
if (!expect_overflow) { | |||||
BOOST_CHECK_EQUAL(result, result_emulated); | |||||
} | } | ||||
BOOST_CHECK_EQUAL(had_overflow, had_overflow_emulated); | |||||
} | } | ||||
} | } | ||||
/** Generate random number in [-2^63; 2^63]. */ | /** Generate random number in [-2^63; 2^63]. */ | ||||
int64_t GenInt63(MMIXLinearCongruentialGenerator &lcg) { | int64_t GenInt63(MMIXLinearCongruentialGenerator &lcg) { | ||||
while (true) { | while (true) { | ||||
// Uniform number in [-2^63; 2^63]. | // Uniform number in [-2^63; 2^63]. | ||||
int64_t val = (int64_t(lcg.next()) << 32) | lcg.next(); | int64_t val = (int64_t(lcg.next()) << 32) | lcg.next(); | ||||
Show All 28 Lines |