From dc44aad346720c143874ad45741df083e181ee6e Mon Sep 17 00:00:00 2001 From: V Date: Tue, 13 Jan 2026 20:07:05 +0300 Subject: [PATCH 1/2] Add uint ctor from builtin_uint128 to avoid truncation Add an implicit converting constructor for uint (N >= 128) from builtin_uint128 so that uint256{__uint128_t} / static_cast(__uint128_t) correctly zero-extend and preserve the high 64 bits instead of going through the variadic uint64_t-convertible ctor and truncating to 64 bits --- include/intx/intx.hpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/include/intx/intx.hpp b/include/intx/intx.hpp index eb53d119..f33a7a14 100644 --- a/include/intx/intx.hpp +++ b/include/intx/intx.hpp @@ -891,6 +891,12 @@ struct uint words_[i] = x[i]; } + #if INTX_HAS_BUILTIN_INT128 + constexpr explicit(false) uint(builtin_uint128 x) noexcept + : words_{uint64_t(x), uint64_t(x >> 64)} + {} + #endif + template constexpr explicit(false) uint(T... v) noexcept requires std::conjunction_v...> From 33fdc132f16ce4a25c372246852e4ea3df7a93ff Mon Sep 17 00:00:00 2001 From: Valeriy Date: Sat, 17 Jan 2026 20:15:07 +0300 Subject: [PATCH 2/2] Add test for uint256 conversion from builtin_uint128 Add test for uint256 conversion from builtin_uint128 --- test/unittests/test_uint256.cpp | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/unittests/test_uint256.cpp b/test/unittests/test_uint256.cpp index f2bec334..1679fe34 100644 --- a/test/unittests/test_uint256.cpp +++ b/test/unittests/test_uint256.cpp @@ -226,3 +226,17 @@ TEST(uint256, mulmod) const auto b = 0x8c9f09b6227ba6542a97343c679e1d11d8bfa29228c18615c2_u256; EXPECT_EQ(mulmod(a, b, mod), 0xca283039a2ad0dbd3d60fbadb29e9c7a_u128); } + +#if INTX_HAS_BUILTIN_INT128 +TEST(uint256, conversion_from_builtin_uint128) +{ + const builtin_uint128 x = (builtin_uint128{1} << 64) | builtin_uint128{2}; + + const auto a = uint256{x}; + const auto b = static_cast(x); + const auto expected = uint256{uint64_t{2}, uint64_t{1}}; + + EXPECT_EQ(a, expected); + EXPECT_EQ(b, expected); +} +#endif