MCPcopy Create free account
hub / github.com/FlaxEngine/FlaxEngine / format_float

Function format_float

Source/ThirdParty/fmt/format-inl.h:1730–1814  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1728
1729template <typename Float>
1730int format_float(Float value, int precision, float_specs specs, buffer<char>& buf) {
1731 // float is passed as double to reduce the number of instantiations.
1732 static_assert(!std::is_same<Float, float>::value, "");
1733 FMT_ASSERT(value >= 0, "value is negative");
1734 auto converted_value = convert_float(value);
1735
1736 const bool fixed = specs.format == float_format::fixed;
1737 if (value <= 0) { // <= instead of == to silence a warning.
1738 if (precision <= 0 || !fixed) {
1739 buf.push_back('0');
1740 return 0;
1741 }
1742 buf.try_resize(to_unsigned(precision));
1743 fill_n(buf.data(), precision, '0');
1744 return -precision;
1745 }
1746
1747 int exp = 0;
1748 bool use_dragon = true;
1749 unsigned dragon_flags = 0;
1750 if (!is_fast_float<Float>()) {
1751 const auto inv_log2_10 = 0.3010299956639812; // 1 / log2(10)
1752 using info = dragonbox::float_info<decltype(converted_value)>;
1753 const auto f = basic_fp<typename info::carrier_uint>(converted_value);
1754 // Compute exp, an approximate power of 10, such that
1755 // 10^(exp - 1) <= value < 10^exp or 10^exp <= value < 10^(exp + 1).
1756 // This is based on log10(value) == log2(value) / log2(10) and approximation
1757 // of log2(value) by e + num_fraction_bits idea from double-conversion.
1758 exp = static_cast<int>(
1759 ::ceil((f.e + count_digits<1>(f.f) - 1) * inv_log2_10 - 1e-10));
1760 dragon_flags = dragon::fixup;
1761 } else if (!is_constant_evaluated() && precision < 0) {
1762 // Use Dragonbox for the shortest format.
1763 if (specs.binary32) {
1764 auto dec = dragonbox::to_decimal(static_cast<float>(value));
1765 write<char>(buffer_appender<char>(buf), dec.significand);
1766 return dec.exponent;
1767 }
1768 auto dec = dragonbox::to_decimal(static_cast<double>(value));
1769 write<char>(buffer_appender<char>(buf), dec.significand);
1770 return dec.exponent;
1771 } else {
1772 // Use Grisu + Dragon4 for the given precision:
1773 // https://www.cs.tufts.edu/~nr/cs257/archive/florian-loitsch/printf.pdf.
1774 const int min_exp = -60; // alpha in Grisu.
1775 int cached_exp10 = 0; // K in Grisu.
1776 fp normalized = normalize(fp(converted_value));
1777 const auto cached_pow = get_cached_power(
1778 min_exp - (normalized.e + fp::num_significand_bits), cached_exp10);
1779 normalized = normalized * cached_pow;
1780 gen_digits_handler handler{buf.data(), 0, precision, -cached_exp10, fixed};
1781 if (grisu_gen_digits(normalized, 1, exp, handler) != digits::error &&
1782 !is_constant_evaluated()) {
1783 exp += handler.exp10;
1784 buf.try_resize(to_unsigned(handler.size));
1785 use_dragon = false;
1786 } else {
1787 exp += handler.size - cached_exp10 - 1;

Callers 1

writeFunction · 0.85

Calls 14

convert_floatFunction · 0.85
to_unsignedFunction · 0.85
fill_nFunction · 0.85
ceilFunction · 0.85
to_decimalFunction · 0.85
get_cached_powerFunction · 0.85
grisu_gen_digitsFunction · 0.85
format_dragonFunction · 0.85
normalizeFunction · 0.50
push_backMethod · 0.45
try_resizeMethod · 0.45
dataMethod · 0.45

Tested by

no test coverage detected