mirror of
https://github.com/fmtlib/fmt.git
synced 2025-07-30 10:47:35 +02:00
Add support for extended precision FP
This commit is contained in:
@ -444,9 +444,6 @@ class bigint {
|
|||||||
public:
|
public:
|
||||||
FMT_CONSTEXPR20 bigint() : exp_(0) {}
|
FMT_CONSTEXPR20 bigint() : exp_(0) {}
|
||||||
explicit bigint(uint64_t n) { assign(n); }
|
explicit bigint(uint64_t n) { assign(n); }
|
||||||
FMT_CONSTEXPR20 ~bigint() {
|
|
||||||
FMT_ASSERT(bigits_.capacity() <= bigits_capacity, "");
|
|
||||||
}
|
|
||||||
|
|
||||||
bigint(const bigint&) = delete;
|
bigint(const bigint&) = delete;
|
||||||
void operator=(const bigint&) = delete;
|
void operator=(const bigint&) = delete;
|
||||||
@ -684,6 +681,14 @@ struct gen_digits_handler {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
inline FMT_CONSTEXPR20 void adjust_precision(int& precision, int exp10) {
|
||||||
|
// Adjust fixed precision by exponent because it is relative to decimal
|
||||||
|
// point.
|
||||||
|
if (exp10 > 0 && precision > max_value<int>() - exp10)
|
||||||
|
FMT_THROW(format_error("number is too big"));
|
||||||
|
precision += exp10;
|
||||||
|
}
|
||||||
|
|
||||||
// Generates output using the Grisu digit-gen algorithm.
|
// Generates output using the Grisu digit-gen algorithm.
|
||||||
// error: the size of the region (lower, upper) outside of which numbers
|
// error: the size of the region (lower, upper) outside of which numbers
|
||||||
// definitely do not round to value (Delta in Grisu3).
|
// definitely do not round to value (Delta in Grisu3).
|
||||||
@ -701,14 +706,7 @@ FMT_INLINE FMT_CONSTEXPR20 digits::result grisu_gen_digits(
|
|||||||
exp = count_digits(integral); // kappa in Grisu.
|
exp = count_digits(integral); // kappa in Grisu.
|
||||||
// Non-fixed formats require at least one digit and no precision adjustment.
|
// Non-fixed formats require at least one digit and no precision adjustment.
|
||||||
if (handler.fixed) {
|
if (handler.fixed) {
|
||||||
// Adjust fixed precision by exponent because it is relative to decimal
|
adjust_precision(handler.precision, exp + handler.exp10);
|
||||||
// point.
|
|
||||||
int precision_offset = exp + handler.exp10;
|
|
||||||
if (precision_offset > 0 &&
|
|
||||||
handler.precision > max_value<int>() - precision_offset) {
|
|
||||||
FMT_THROW(format_error("number is too big"));
|
|
||||||
}
|
|
||||||
handler.precision += precision_offset;
|
|
||||||
// Check if precision is satisfied just by leading zeros, e.g.
|
// Check if precision is satisfied just by leading zeros, e.g.
|
||||||
// format("{:.2f}", 0.001) gives "0.00" without generating any digits.
|
// format("{:.2f}", 0.001) gives "0.00" without generating any digits.
|
||||||
if (handler.precision <= 0) {
|
if (handler.precision <= 0) {
|
||||||
@ -2277,6 +2275,9 @@ FMT_HEADER_ONLY_CONSTEXPR20 int format_float(Float value, int precision,
|
|||||||
exp += handler.size - cached_exp10 - 1;
|
exp += handler.size - cached_exp10 - 1;
|
||||||
precision = handler.precision;
|
precision = handler.precision;
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
exp = static_cast<int>(std::log10(value));
|
||||||
|
if (fixed) adjust_precision(precision, exp + 1);
|
||||||
}
|
}
|
||||||
if (use_dragon) {
|
if (use_dragon) {
|
||||||
auto f = fp();
|
auto f = fp();
|
||||||
|
@ -2233,7 +2233,8 @@ FMT_CONSTEXPR20 auto write(OutputIt out, T value,
|
|||||||
++precision;
|
++precision;
|
||||||
}
|
}
|
||||||
if (const_check(std::is_same<T, float>())) fspecs.binary32 = true;
|
if (const_check(std::is_same<T, float>())) fspecs.binary32 = true;
|
||||||
if (!is_fast_float<T>()) fspecs.fallback = true;
|
if (!std::numeric_limits<T>::is_iec559 || std::numeric_limits<T>::digits > 64)
|
||||||
|
fspecs.fallback = true;
|
||||||
int exp = format_float(convert_float(value), precision, fspecs, buffer);
|
int exp = format_float(convert_float(value), precision, fspecs, buffer);
|
||||||
fspecs.precision = precision;
|
fspecs.precision = precision;
|
||||||
auto fp = big_decimal_fp{buffer.data(), static_cast<int>(buffer.size()), exp};
|
auto fp = big_decimal_fp{buffer.data(), static_cast<int>(buffer.size()), exp};
|
||||||
|
Reference in New Issue
Block a user