mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-30 10:47:35 +02:00
Cleanup bigint
This commit is contained in:
@ -729,8 +729,7 @@ FMT_CONSTEXPR inline auto compute_width(string_view s) -> size_t {
|
|||||||
|
|
||||||
template <typename Char>
|
template <typename Char>
|
||||||
inline auto code_point_index(basic_string_view<Char> s, size_t n) -> size_t {
|
inline auto code_point_index(basic_string_view<Char> s, size_t n) -> size_t {
|
||||||
size_t size = s.size();
|
return min_of(n, s.size());
|
||||||
return n < size ? n : size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Calculates the index of the nth code point in a UTF-8 string.
|
// Calculates the index of the nth code point in a UTF-8 string.
|
||||||
@ -858,7 +857,7 @@ class basic_memory_buffer : public detail::buffer<T> {
|
|||||||
if (size > new_capacity)
|
if (size > new_capacity)
|
||||||
new_capacity = size;
|
new_capacity = size;
|
||||||
else if (new_capacity > max_size)
|
else if (new_capacity > max_size)
|
||||||
new_capacity = size > max_size ? size : max_size;
|
new_capacity = max_of(size, max_size);
|
||||||
T* old_data = buf.data();
|
T* old_data = buf.data();
|
||||||
T* new_data = self.alloc_.allocate(new_capacity);
|
T* new_data = self.alloc_.allocate(new_capacity);
|
||||||
// Suppress a bogus -Wstringop-overflow in gcc 13.1 (#3481).
|
// Suppress a bogus -Wstringop-overflow in gcc 13.1 (#3481).
|
||||||
@ -2560,7 +2559,7 @@ FMT_CONSTEXPR20 auto do_write_float(OutputIt out, const DecimalFP& f,
|
|||||||
} else if (exp > 0) {
|
} else if (exp > 0) {
|
||||||
// 1234e-2 -> 12.34[0+]
|
// 1234e-2 -> 12.34[0+]
|
||||||
int num_zeros = specs.alt() ? specs.precision - significand_size : 0;
|
int num_zeros = specs.alt() ? specs.precision - significand_size : 0;
|
||||||
size += 1 + to_unsigned(num_zeros > 0 ? num_zeros : 0);
|
size += 1 + static_cast<unsigned>(max_of(num_zeros, 0));
|
||||||
auto grouping = Grouping(loc, specs.localized());
|
auto grouping = Grouping(loc, specs.localized());
|
||||||
size += to_unsigned(grouping.count_separators(exp));
|
size += to_unsigned(grouping.count_separators(exp));
|
||||||
return write_padded<Char, align::right>(out, specs, size, [&](iterator it) {
|
return write_padded<Char, align::right>(out, specs, size, [&](iterator it) {
|
||||||
@ -2673,26 +2672,19 @@ class bigint {
|
|||||||
|
|
||||||
friend struct formatter<bigint>;
|
friend struct formatter<bigint>;
|
||||||
|
|
||||||
FMT_CONSTEXPR auto operator[](int index) const -> bigit {
|
|
||||||
return bigits_[to_unsigned(index)];
|
|
||||||
}
|
|
||||||
FMT_CONSTEXPR auto operator[](int index) -> bigit& {
|
|
||||||
return bigits_[to_unsigned(index)];
|
|
||||||
}
|
|
||||||
|
|
||||||
FMT_CONSTEXPR auto get_bigit(int i) const -> bigit {
|
FMT_CONSTEXPR auto get_bigit(int i) const -> bigit {
|
||||||
return i >= exp_ && i < num_bigits() ? bigits_[i - exp_] : 0;
|
return i >= exp_ && i < num_bigits() ? bigits_[i - exp_] : 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
FMT_CONSTEXPR void subtract_bigits(int index, bigit other, bigit& borrow) {
|
FMT_CONSTEXPR void subtract_bigits(int index, bigit other, bigit& borrow) {
|
||||||
auto result = static_cast<double_bigit>((*this)[index]) - other - borrow;
|
auto result = double_bigit(bigits_[index]) - other - borrow;
|
||||||
(*this)[index] = static_cast<bigit>(result);
|
bigits_[index] = static_cast<bigit>(result);
|
||||||
borrow = static_cast<bigit>(result >> (bigit_bits * 2 - 1));
|
borrow = static_cast<bigit>(result >> (bigit_bits * 2 - 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
FMT_CONSTEXPR void remove_leading_zeros() {
|
FMT_CONSTEXPR void remove_leading_zeros() {
|
||||||
int num_bigits = static_cast<int>(bigits_.size()) - 1;
|
int num_bigits = static_cast<int>(bigits_.size()) - 1;
|
||||||
while (num_bigits > 0 && (*this)[num_bigits] == 0) --num_bigits;
|
while (num_bigits > 0 && bigits_[num_bigits] == 0) --num_bigits;
|
||||||
bigits_.resize(to_unsigned(num_bigits + 1));
|
bigits_.resize(to_unsigned(num_bigits + 1));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2704,13 +2696,14 @@ class bigint {
|
|||||||
int i = other.exp_ - exp_;
|
int i = other.exp_ - exp_;
|
||||||
for (size_t j = 0, n = other.bigits_.size(); j != n; ++i, ++j)
|
for (size_t j = 0, n = other.bigits_.size(); j != n; ++i, ++j)
|
||||||
subtract_bigits(i, other.bigits_[j], borrow);
|
subtract_bigits(i, other.bigits_[j], borrow);
|
||||||
while (borrow > 0) subtract_bigits(i, 0, borrow);
|
if (borrow != 0) subtract_bigits(i, 0, borrow);
|
||||||
|
FMT_ASSERT(borrow == 0, "");
|
||||||
remove_leading_zeros();
|
remove_leading_zeros();
|
||||||
}
|
}
|
||||||
|
|
||||||
FMT_CONSTEXPR void multiply(uint32_t value) {
|
FMT_CONSTEXPR void multiply(uint32_t value) {
|
||||||
const double_bigit wide_value = value;
|
|
||||||
bigit carry = 0;
|
bigit carry = 0;
|
||||||
|
const double_bigit wide_value = value;
|
||||||
for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
|
for (size_t i = 0, n = bigits_.size(); i < n; ++i) {
|
||||||
double_bigit result = bigits_[i] * wide_value + carry;
|
double_bigit result = bigits_[i] * wide_value + carry;
|
||||||
bigits_[i] = static_cast<bigit>(result);
|
bigits_[i] = static_cast<bigit>(result);
|
||||||
@ -2807,7 +2800,7 @@ class bigint {
|
|||||||
int end = i - j;
|
int end = i - j;
|
||||||
if (end < 0) end = 0;
|
if (end < 0) end = 0;
|
||||||
for (; i >= end; --i, --j) {
|
for (; i >= end; --i, --j) {
|
||||||
bigit lhs_bigit = lhs[i], rhs_bigit = rhs[j];
|
bigit lhs_bigit = lhs.bigits_[i], rhs_bigit = rhs.bigits_[j];
|
||||||
if (lhs_bigit != rhs_bigit) return lhs_bigit > rhs_bigit ? 1 : -1;
|
if (lhs_bigit != rhs_bigit) return lhs_bigit > rhs_bigit ? 1 : -1;
|
||||||
}
|
}
|
||||||
if (i != j) return i > j ? 1 : -1;
|
if (i != j) return i > j ? 1 : -1;
|
||||||
@ -2824,8 +2817,7 @@ class bigint {
|
|||||||
double_bigit borrow = 0;
|
double_bigit borrow = 0;
|
||||||
int min_exp = min_of(min_of(lhs1.exp_, lhs2.exp_), rhs.exp_);
|
int min_exp = min_of(min_of(lhs1.exp_, lhs2.exp_), rhs.exp_);
|
||||||
for (int i = num_rhs_bigits - 1; i >= min_exp; --i) {
|
for (int i = num_rhs_bigits - 1; i >= min_exp; --i) {
|
||||||
double_bigit sum =
|
double_bigit sum = double_bigit(lhs1.get_bigit(i)) + lhs2.get_bigit(i);
|
||||||
static_cast<double_bigit>(lhs1.get_bigit(i)) + lhs2.get_bigit(i);
|
|
||||||
bigit rhs_bigit = rhs.get_bigit(i);
|
bigit rhs_bigit = rhs.get_bigit(i);
|
||||||
if (sum > rhs_bigit + borrow) return 1;
|
if (sum > rhs_bigit + borrow) return 1;
|
||||||
borrow = rhs_bigit + borrow - sum;
|
borrow = rhs_bigit + borrow - sum;
|
||||||
@ -2866,17 +2858,17 @@ class bigint {
|
|||||||
// cross-product terms n[i] * n[j] such that i + j == bigit_index.
|
// cross-product terms n[i] * n[j] such that i + j == bigit_index.
|
||||||
for (int i = 0, j = bigit_index; j >= 0; ++i, --j) {
|
for (int i = 0, j = bigit_index; j >= 0; ++i, --j) {
|
||||||
// Most terms are multiplied twice which can be optimized in the future.
|
// Most terms are multiplied twice which can be optimized in the future.
|
||||||
sum += static_cast<double_bigit>(n[i]) * n[j];
|
sum += double_bigit(n[i]) * n[j];
|
||||||
}
|
}
|
||||||
(*this)[bigit_index] = static_cast<bigit>(sum);
|
bigits_[bigit_index] = static_cast<bigit>(sum);
|
||||||
sum >>= num_bits<bigit>(); // Compute the carry.
|
sum >>= num_bits<bigit>(); // Compute the carry.
|
||||||
}
|
}
|
||||||
// Do the same for the top half.
|
// Do the same for the top half.
|
||||||
for (int bigit_index = num_bigits; bigit_index < num_result_bigits;
|
for (int bigit_index = num_bigits; bigit_index < num_result_bigits;
|
||||||
++bigit_index) {
|
++bigit_index) {
|
||||||
for (int j = num_bigits - 1, i = bigit_index - j; i < num_bigits;)
|
for (int j = num_bigits - 1, i = bigit_index - j; i < num_bigits;)
|
||||||
sum += static_cast<double_bigit>(n[i++]) * n[j--];
|
sum += double_bigit(n[i++]) * n[j--];
|
||||||
(*this)[bigit_index] = static_cast<bigit>(sum);
|
bigits_[bigit_index] = static_cast<bigit>(sum);
|
||||||
sum >>= num_bits<bigit>();
|
sum >>= num_bits<bigit>();
|
||||||
}
|
}
|
||||||
remove_leading_zeros();
|
remove_leading_zeros();
|
||||||
@ -3286,7 +3278,7 @@ FMT_CONSTEXPR20 auto format_float(Float value, int precision,
|
|||||||
uint64_t prod;
|
uint64_t prod;
|
||||||
uint32_t digits;
|
uint32_t digits;
|
||||||
bool should_round_up;
|
bool should_round_up;
|
||||||
int number_of_digits_to_print = precision > 9 ? 9 : precision;
|
int number_of_digits_to_print = min_of(precision, 9);
|
||||||
|
|
||||||
// Print a 9-digits subsegment, either the first or the second.
|
// Print a 9-digits subsegment, either the first or the second.
|
||||||
auto print_subsegment = [&](uint32_t subsegment, char* buffer) {
|
auto print_subsegment = [&](uint32_t subsegment, char* buffer) {
|
||||||
@ -4269,8 +4261,7 @@ template <typename T, FMT_ENABLE_IF(std::is_integral<T>::value)>
|
|||||||
FMT_NODISCARD auto to_string(T value) -> std::string {
|
FMT_NODISCARD auto to_string(T value) -> std::string {
|
||||||
// The buffer should be large enough to store the number including the sign
|
// The buffer should be large enough to store the number including the sign
|
||||||
// or "false" for bool.
|
// or "false" for bool.
|
||||||
constexpr int max_size = detail::digits10<T>() + 2;
|
char buffer[max_of(detail::digits10<T>() + 2, 5)];
|
||||||
char buffer[max_size > 5 ? static_cast<unsigned>(max_size) : 5];
|
|
||||||
char* begin = buffer;
|
char* begin = buffer;
|
||||||
return {buffer, detail::write<char>(begin, value)};
|
return {buffer, detail::write<char>(begin, value)};
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user