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

Method format_float

include/fmt/format.h:3001–3288  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2999
3000template <typename Float>
3001FMT_CONSTEXPR20 auto format_float(Float value, int precision, float_specs specs, buffer<char>& buf) -> int {
3002 // float is passed as double to reduce the number of instantiations.
3003 static_assert(!std::is_same<Float, float>::value, "");
3004 FMT_ASSERT(value >= 0, "value is negative");
3005 auto converted_value = convert_float(value);
3006
3007 const bool fixed = specs.format == float_format::fixed;
3008 if (value <= 0) { // <= instead of == to silence a warning.
3009 if (precision <= 0 || !fixed) {
3010 buf.push_back('0');
3011 return 0;
3012 }
3013 buf.try_resize(to_unsigned(precision));
3014 fill_n(buf.data(), precision, '0');
3015 return -precision;
3016 }
3017
3018 int exp = 0;
3019 bool use_dragon = true;
3020 unsigned dragon_flags = 0;
3021 if (!is_fast_float<Float>() || is_constant_evaluated()) {
3022 const auto inv_log2_10 = 0.3010299956639812; // 1 / log2(10)
3023 using info = dragonbox::float_info<decltype(converted_value)>;
3024 const auto f = basic_fp<typename info::carrier_uint>(converted_value);
3025 // Compute exp, an approximate power of 10, such that
3026 // 10^(exp - 1) <= value < 10^exp or 10^exp <= value < 10^(exp + 1).
3027 // This is based on log10(value) == log2(value) / log2(10) and approximation
3028 // of log2(value) by e + num_fraction_bits idea from double-conversion.
3029 auto e = (f.e + count_digits<1>(f.f) - 1) * inv_log2_10 - 1e-10;
3030 exp = static_cast<int>(e);
3031 if (e > exp) ++exp; // Compute ceil.
3032 dragon_flags = dragon::fixup;
3033 } else if (precision < 0) {
3034 // Use Dragonbox for the shortest format.
3035 if (specs.binary32) {
3036 auto dec = dragonbox::to_decimal(static_cast<float>(value));
3037 write<char>(buffer_appender<char>(buf), dec.significand);
3038 return dec.exponent;
3039 }
3040 auto dec = dragonbox::to_decimal(static_cast<double>(value));
3041 write<char>(buffer_appender<char>(buf), dec.significand);
3042 return dec.exponent;
3043 } else {
3044 // Extract significand bits and exponent bits.
3045 using info = dragonbox::float_info<double>;
3046 auto br = bit_cast<uint64_t>(static_cast<double>(value));
3047
3048 const uint64_t significand_mask = (static_cast<uint64_t>(1) << num_significand_bits<double>()) - 1;
3049 uint64_t significand = (br & significand_mask);
3050 int exponent = static_cast<int>((br & exponent_mask<double>()) >> num_significand_bits<double>());
3051
3052 if (exponent != 0) { // Check if normal.
3053 exponent -= exponent_bias<double>() + num_significand_bits<double>();
3054 significand |= (static_cast<uint64_t>(1) << num_significand_bits<double>());
3055 significand <<= 1;
3056 } else {
3057 // Normalize subnormal inputs.
3058 FMT_ASSERT(significand != 0, "zeros should not appear here");

Callers

nothing calls this directly

Calls 15

convert_floatFunction · 0.85
to_unsignedFunction · 0.85
fill_nFunction · 0.85
is_constant_evaluatedFunction · 0.85
to_decimalFunction · 0.85
countl_zeroFunction · 0.85
floor_log10_pow2Function · 0.85
floor_log2_pow10Function · 0.85
umul192_upper128Function · 0.85
umul128_upper64Function · 0.85
copy2Function · 0.85
digits2Function · 0.85

Tested by

no test coverage detected