mirror of
https://github.com/fmtlib/fmt.git
synced 2025-11-28 13:19:48 +01:00
Add partial support for extended precision FP
This commit is contained in:
@@ -1198,7 +1198,7 @@ class utf8_to_utf16 {
|
||||
namespace dragonbox {
|
||||
|
||||
// Type-specific information that Dragonbox uses.
|
||||
template <class T> struct float_info;
|
||||
template <typename T, typename Enable = void> struct float_info;
|
||||
|
||||
template <> struct float_info<float> {
|
||||
using carrier_uint = uint32_t;
|
||||
@@ -1246,6 +1246,15 @@ template <> struct float_info<double> {
|
||||
static const int max_trailing_zeros = 16;
|
||||
};
|
||||
|
||||
// 80-bit extended precision long double.
|
||||
template <typename T>
|
||||
struct float_info<T, enable_if_t<std::is_same<T, long double>::value &&
|
||||
std::numeric_limits<T>::digits == 64>> {
|
||||
using carrier_uint = detail::uint128_t;
|
||||
static const int significand_bits = 64;
|
||||
static const int exponent_bits = 15;
|
||||
};
|
||||
|
||||
template <typename T> struct decimal_fp {
|
||||
using significand_type = typename float_info<T>::carrier_uint;
|
||||
significand_type significand;
|
||||
@@ -1295,11 +1304,14 @@ template <typename T>
|
||||
auto snprintf_float(T value, int precision, float_specs specs,
|
||||
buffer<char>& buf) -> int;
|
||||
|
||||
template <typename T> constexpr auto promote_float(T value) -> T {
|
||||
return value;
|
||||
}
|
||||
constexpr auto promote_float(float value) -> double {
|
||||
return static_cast<double>(value);
|
||||
template <typename T>
|
||||
using convert_float_result =
|
||||
conditional_t<std::is_same<T, float>::value || sizeof(T) == sizeof(double),
|
||||
double, T>;
|
||||
|
||||
template <typename T>
|
||||
constexpr auto convert_float(T value) -> convert_float_result<T> {
|
||||
return static_cast<convert_float_result<T>>(value);
|
||||
}
|
||||
|
||||
template <typename OutputIt, typename Char>
|
||||
@@ -2207,7 +2219,7 @@ FMT_CONSTEXPR20 auto write(OutputIt out, T value,
|
||||
memory_buffer buffer;
|
||||
if (fspecs.format == float_format::hex) {
|
||||
if (fspecs.sign) buffer.push_back(detail::sign<char>(fspecs.sign));
|
||||
snprintf_float(promote_float(value), specs.precision, fspecs, buffer);
|
||||
snprintf_float(convert_float(value), specs.precision, fspecs, buffer);
|
||||
return write_bytes<align::right>(out, {buffer.data(), buffer.size()},
|
||||
specs);
|
||||
}
|
||||
@@ -2222,7 +2234,7 @@ FMT_CONSTEXPR20 auto write(OutputIt out, T value,
|
||||
}
|
||||
if (const_check(std::is_same<T, float>())) fspecs.binary32 = true;
|
||||
if (!is_fast_float<T>()) fspecs.fallback = true;
|
||||
int exp = format_float(promote_float(value), precision, fspecs, buffer);
|
||||
int exp = format_float(convert_float(value), precision, fspecs, buffer);
|
||||
fspecs.precision = precision;
|
||||
auto fp = big_decimal_fp{buffer.data(), static_cast<int>(buffer.size()), exp};
|
||||
return write_float(out, fp, specs, fspecs, loc);
|
||||
|
||||
Reference in New Issue
Block a user