mirror of
https://github.com/bitcoin/bitcoin.git
synced 2026-04-09 07:08:25 +02:00
Merge bitcoin/bitcoin#34436: refactor: add overflow-safe CeilDiv helper and use it in unsigned callsites
02d047fd5brefactor: add overflow-safe `CeilDiv` helper (Lőrinc) Pull request description: ### Problem The codebase has many open-coded ceiling-division expressions (for example `(x+y-1)/y`) scattered across files. These are less readable, duplicate logic, and can be overflow-prone in edge cases. ### Fix Introduce a small overflow-safe integer helper, `CeilDiv()`, and use it in existing **unsigned** callsites where the conversion is straightforward and noise-free. ### What this PR does * Adds `CeilDiv()` to `src/util/overflow.h` for unsigned integral inputs. * Keeps the precondition check `assert(divisor > 0)`. * Replaces selected unsigned ceiling-division expressions with `CeilDiv(...)`. * Adds focused unit tests in `src/test/util_tests.cpp` for the migrated patterns. --- This is a pure refactor with no intended behavioral change. Signed arithmetic callsites are intentionally left unchanged in this PR. This PR changed a few more things originally but based on feedback reverted to the simplest cases only. ACKs for top commit: rustaceanrob: ACK02d047fd5bhodlinator: ACK02d047fd5bsedited: ACK02d047fd5bTree-SHA512: b09336031f487e6ce289822e0ffeb8cfc8cfe8a2f4f3f49470748dfbd0a6cbab97498674cb8686dd2bd4ab6dd0b79cfdf2da00041fee12d109892e1bc5dde0ff
This commit is contained in:
@@ -1834,4 +1834,41 @@ BOOST_AUTO_TEST_CASE(mib_string_literal_test)
|
||||
BOOST_CHECK_EXCEPTION(operator""_MiB(static_cast<unsigned long long>(max_mib) + 1), std::overflow_error, HasReason("MiB value too large for size_t byte conversion"));
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_CASE(ceil_div_test)
|
||||
{
|
||||
// Type combinations used by current CeilDiv callsites.
|
||||
BOOST_CHECK((std::is_same_v<decltype(CeilDiv(uint32_t{0}, 8u)), uint32_t>));
|
||||
BOOST_CHECK((std::is_same_v<decltype(CeilDiv(size_t{0}, 8u)), size_t>));
|
||||
BOOST_CHECK((std::is_same_v<decltype(CeilDiv(unsigned{0}, size_t{1})), size_t>));
|
||||
|
||||
// `common/bloom.cpp` and `cuckoocache.h` patterns.
|
||||
BOOST_CHECK_EQUAL(CeilDiv(uint32_t{3}, 2u), uint32_t{2});
|
||||
BOOST_CHECK_EQUAL(CeilDiv(uint32_t{65}, 64u), uint32_t{2});
|
||||
BOOST_CHECK_EQUAL(CeilDiv(uint32_t{9}, 8u), uint32_t{2});
|
||||
|
||||
// `key_io.cpp`, `rest.cpp`, `merkleblock.cpp`, `strencodings.cpp` patterns.
|
||||
BOOST_CHECK_EQUAL(CeilDiv(size_t{9}, 8u), size_t{2});
|
||||
BOOST_CHECK_EQUAL(CeilDiv(size_t{10}, 3u), size_t{4});
|
||||
BOOST_CHECK_EQUAL(CeilDiv(size_t{11}, 5u), size_t{3});
|
||||
BOOST_CHECK_EQUAL(CeilDiv(size_t{41} * 8, 5u), size_t{66});
|
||||
|
||||
// `flatfile.cpp` mixed unsigned/size_t pattern.
|
||||
BOOST_CHECK_EQUAL(CeilDiv(unsigned{10}, size_t{4}), size_t{3});
|
||||
|
||||
// `util/feefrac.h` fast-path rounding-up pattern.
|
||||
constexpr int64_t fee{12345};
|
||||
constexpr int32_t at_size{67};
|
||||
constexpr int32_t size{10};
|
||||
BOOST_CHECK_EQUAL(CeilDiv(uint64_t(fee) * at_size, uint32_t(size)),
|
||||
(uint64_t(fee) * at_size + uint32_t(size) - 1) / uint32_t(size));
|
||||
|
||||
// `bitset.h` template parameter pattern.
|
||||
constexpr unsigned bits{129};
|
||||
constexpr size_t digits{std::numeric_limits<size_t>::digits};
|
||||
BOOST_CHECK_EQUAL(CeilDiv(bits, digits), (bits + digits - 1) / digits);
|
||||
|
||||
// `serialize.h` varint scratch-buffer pattern.
|
||||
BOOST_CHECK_EQUAL(CeilDiv(sizeof(uint64_t) * 8, 7u), (sizeof(uint64_t) * 8 + 6) / 7);
|
||||
}
|
||||
|
||||
BOOST_AUTO_TEST_SUITE_END()
|
||||
|
||||
Reference in New Issue
Block a user