mirror of
https://github.com/fmtlib/fmt.git
synced 2025-03-13 19:19:10 +00:00
Implement 128-bit constant mul in bigint
This commit is contained in:
parent
02eb215f2f
commit
686de58886
@ -371,13 +371,16 @@ class bigint {
|
|||||||
template <typename UInt, FMT_ENABLE_IF(std::is_same<UInt, uint64_t>::value ||
|
template <typename UInt, FMT_ENABLE_IF(std::is_same<UInt, uint64_t>::value ||
|
||||||
std::is_same<UInt, uint128_t>::value)>
|
std::is_same<UInt, uint128_t>::value)>
|
||||||
FMT_CONSTEXPR20 void multiply(UInt value) {
|
FMT_CONSTEXPR20 void multiply(UInt value) {
|
||||||
const UInt lower = static_cast<bigit>(value);
|
using half_uint =
|
||||||
const UInt upper = value >> bigit_bits;
|
conditional_t<std::is_same<UInt, uint128_t>::value, uint64_t, uint32_t>;
|
||||||
|
const int shift = num_bits<half_uint>() - bigit_bits;
|
||||||
|
const UInt lower = static_cast<half_uint>(value);
|
||||||
|
const UInt upper = value >> num_bits<half_uint>();
|
||||||
UInt carry = 0;
|
UInt carry = 0;
|
||||||
for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
|
for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
|
||||||
UInt result = lower * bigits_[i] + static_cast<bigit>(carry);
|
UInt result = lower * bigits_[i] + static_cast<bigit>(carry);
|
||||||
carry =
|
carry = (upper * bigits_[i] << shift) + (result >> bigit_bits) +
|
||||||
upper * bigits_[i] + (result >> bigit_bits) + (carry >> bigit_bits);
|
(carry >> bigit_bits);
|
||||||
bigits_[i] = static_cast<bigit>(result);
|
bigits_[i] = static_cast<bigit>(result);
|
||||||
}
|
}
|
||||||
while (carry != 0) {
|
while (carry != 0) {
|
||||||
|
@ -362,9 +362,11 @@ class uint128_fallback {
|
|||||||
result += rhs;
|
result += rhs;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
friend auto operator*(const uint128_fallback&, uint32_t) -> uint128_fallback {
|
friend auto operator*(const uint128_fallback& lhs, uint32_t rhs)
|
||||||
FMT_ASSERT(false, "");
|
-> uint128_fallback {
|
||||||
return {};
|
FMT_ASSERT(lhs.hi_ == 0, "");
|
||||||
|
uint64_t hi = (lhs.lo_ >> 32) * rhs;
|
||||||
|
return {hi >> 32, (hi << 32) + (lhs.lo_ & ~uint32_t()) * rhs};
|
||||||
}
|
}
|
||||||
friend auto operator-(const uint128_fallback& lhs, uint64_t rhs)
|
friend auto operator-(const uint128_fallback& lhs, uint64_t rhs)
|
||||||
-> uint128_fallback {
|
-> uint128_fallback {
|
||||||
|
@ -101,9 +101,9 @@ TEST(bigint_test, multiply) {
|
|||||||
|
|
||||||
const auto max128 = (fmt::detail::uint128_t(max64) << 64) | max64;
|
const auto max128 = (fmt::detail::uint128_t(max64) << 64) | max64;
|
||||||
bigmax = max128;
|
bigmax = max128;
|
||||||
// bigmax *= max128;
|
bigmax *= max128;
|
||||||
// EXPECT_EQ(fmt::to_string(bigmax),
|
EXPECT_EQ(fmt::to_string(bigmax),
|
||||||
// "fffffffffffffffffffffffffffffffe00000000000000000000000000000001");
|
"fffffffffffffffffffffffffffffffe00000000000000000000000000000001");
|
||||||
}
|
}
|
||||||
|
|
||||||
TEST(bigint_test, square) {
|
TEST(bigint_test, square) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user