Merge accumulator into int128_fallback
This commit is contained in:
parent
d38f72aff2
commit
4ddab8901c
@ -142,7 +142,7 @@ FMT_FUNC std::system_error vsystem_error(int error_code, string_view format_str,
|
||||
namespace detail {
|
||||
|
||||
template <> FMT_FUNC int count_digits<4>(detail::uintptr_fallback n) {
|
||||
// fallback_uintptr is always stored in little endian.
|
||||
// uintptr_fallback is always stored in little endian.
|
||||
int i = static_cast<int>(sizeof(void*)) - 1;
|
||||
while (i > 0 && n.value[i] == 0) --i;
|
||||
auto char_digits = std::numeric_limits<unsigned char>::digits / 4;
|
||||
@ -347,29 +347,6 @@ FMT_CONSTEXPR inline fp get_cached_power(int min_exponent,
|
||||
impl_data::pow10_exponents[index]};
|
||||
}
|
||||
|
||||
// A simple accumulator to hold the sums of terms in bigint::square if uint128_t
|
||||
// is not available.
|
||||
struct accumulator {
|
||||
uint64_t lower;
|
||||
uint64_t upper;
|
||||
|
||||
constexpr accumulator() : lower(0), upper(0) {}
|
||||
constexpr explicit operator uint32_t() const {
|
||||
return static_cast<uint32_t>(lower);
|
||||
}
|
||||
|
||||
FMT_CONSTEXPR void operator+=(uint64_t n) {
|
||||
lower += n;
|
||||
if (lower < n) ++upper;
|
||||
}
|
||||
FMT_CONSTEXPR void operator>>=(int shift) {
|
||||
FMT_ASSERT(shift == 32, "");
|
||||
(void)shift;
|
||||
lower = (upper << 32) | (lower >> 32);
|
||||
upper >>= 32;
|
||||
}
|
||||
};
|
||||
|
||||
class bigint {
|
||||
private:
|
||||
// A bigint is stored as an array of bigits (big digits), with bigit at index
|
||||
@ -558,9 +535,7 @@ class bigint {
|
||||
int num_result_bigits = 2 * num_bigits;
|
||||
basic_memory_buffer<bigit, bigits_capacity> n(std::move(bigits_));
|
||||
bigits_.resize(to_unsigned(num_result_bigits));
|
||||
using accumulator_t =
|
||||
conditional_t<FMT_USE_INT128, uint128_opt, accumulator>;
|
||||
auto sum = accumulator_t();
|
||||
auto sum = uint128_t();
|
||||
for (int bigit_index = 0; bigit_index < num_bigits; ++bigit_index) {
|
||||
// Compute bigit at position bigit_index of the result by adding
|
||||
// cross-product terms n[i] * n[j] such that i + j == bigit_index.
|
||||
|
@ -346,8 +346,12 @@ class uint128_fallback {
|
||||
|
||||
public:
|
||||
constexpr uint128_fallback(uint64_t value = 0) : lo_(value), hi_(0) {}
|
||||
explicit operator int() const { return static_cast<int>(lo_); }
|
||||
explicit operator uint64_t() const { return lo_; }
|
||||
|
||||
template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
|
||||
constexpr explicit operator T() const {
|
||||
return static_cast<T>(lo_);
|
||||
}
|
||||
|
||||
friend auto operator==(const uint128_fallback& lhs,
|
||||
const uint128_fallback& rhs) -> bool {
|
||||
return lhs.hi_ == rhs.hi_ && lhs.lo_ == rhs.lo_;
|
||||
@ -361,14 +365,19 @@ class uint128_fallback {
|
||||
FMT_ASSERT(lhs.lo_ >= rhs, "");
|
||||
return {lhs.hi_, lhs.lo_ - rhs};
|
||||
}
|
||||
auto operator>>(int shift) const -> uint128_fallback {
|
||||
FMT_CONSTEXPR auto operator>>(int shift) const -> uint128_fallback {
|
||||
if (shift == 64) return {0, hi_};
|
||||
return {hi_ >> shift, (hi_ << (64 - shift)) | (lo_ >> shift)};
|
||||
}
|
||||
auto operator<<(int shift) const -> uint128_fallback {
|
||||
FMT_CONSTEXPR auto operator<<(int shift) const -> uint128_fallback {
|
||||
if (shift == 64) return {lo_, 0};
|
||||
return {hi_ << shift | (lo_ >> (64 - shift)), (lo_ << shift)};
|
||||
}
|
||||
FMT_CONSTEXPR void operator>>=(int shift) { *this = *this >> shift; }
|
||||
FMT_CONSTEXPR void operator+=(uint64_t n) {
|
||||
lo_ += n;
|
||||
if (lo_ < n) ++hi_;
|
||||
}
|
||||
};
|
||||
|
||||
using uint128_t = conditional_t<FMT_USE_INT128, uint128_opt, uint128_fallback>;
|
||||
|
@ -96,23 +96,6 @@ TEST(bigint_test, multiply) {
|
||||
EXPECT_EQ("fffffffffffffffe0000000000000001", fmt::format("{}", bigmax));
|
||||
}
|
||||
|
||||
TEST(bigint_test, accumulator) {
|
||||
fmt::detail::accumulator acc;
|
||||
EXPECT_EQ(acc.lower, 0);
|
||||
EXPECT_EQ(acc.upper, 0);
|
||||
acc.upper = 12;
|
||||
acc.lower = 34;
|
||||
EXPECT_EQ(static_cast<uint32_t>(acc), 34);
|
||||
acc += 56;
|
||||
EXPECT_EQ(acc.lower, 90);
|
||||
acc += max_value<uint64_t>();
|
||||
EXPECT_EQ(acc.upper, 13);
|
||||
EXPECT_EQ(acc.lower, 89);
|
||||
acc >>= 32;
|
||||
EXPECT_EQ(acc.upper, 0);
|
||||
EXPECT_EQ(acc.lower, 13 * 0x100000000);
|
||||
}
|
||||
|
||||
TEST(bigint_test, square) {
|
||||
bigint n0(0);
|
||||
n0.square();
|
||||
|
Loading…
Reference in New Issue
Block a user