MCPcopy Create free account
hub / github.com/fmtlib/fmt / format_float

Method format_float

include/fmt/format.h:3170–3466  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

3168
3169template <typename Float>
3170FMT_CONSTEXPR20 auto format_float(Float value, int precision,
3171 const format_specs& specs, bool binary32,
3172 buffer<char>& buf) -> int {
3173 // float is passed as double to reduce the number of instantiations.
3174 static_assert(!std::is_same<Float, float>::value, "");
3175 auto converted_value = convert_float(value);
3176
3177 const bool fixed = specs.type() == presentation_type::fixed;
3178 if (value == 0) {
3179 if (precision <= 0 || !fixed) {
3180 buf.push_back('0');
3181 return 0;
3182 }
3183 buf.try_resize(to_unsigned(precision));
3184 fill_n(buf.data(), precision, '0');
3185 return -precision;
3186 }
3187
3188 int exp = 0;
3189 bool use_dragon = true;
3190 unsigned dragon_flags = 0;
3191 if (!is_fast_float<Float>() || is_constant_evaluated()) {
3192 const auto inv_log2_10 = 0.3010299956639812; // 1 / log2(10)
3193 using info = dragonbox::float_info<decltype(converted_value)>;
3194 const auto f = basic_fp<typename info::carrier_uint>(converted_value);
3195 // Compute exp, an approximate power of 10, such that
3196 // 10^(exp - 1) <= value < 10^exp or 10^exp <= value < 10^(exp + 1).
3197 // This is based on log10(value) == log2(value) / log2(10) and approximation
3198 // of log2(value) by e + num_fraction_bits idea from double-conversion.
3199 auto e = (f.e + count_digits<1>(f.f) - 1) * inv_log2_10 - 1e-10;
3200 exp = static_cast<int>(e);
3201 if (e > exp) ++exp; // Compute ceil.
3202 dragon_flags = dragon::fixup;
3203 } else {
3204 // Extract significand bits and exponent bits.
3205 using info = dragonbox::float_info<double>;
3206 auto br = bit_cast<uint64_t>(static_cast<double>(value));
3207
3208 const uint64_t significand_mask =
3209 (static_cast<uint64_t>(1) << num_significand_bits<double>()) - 1;
3210 uint64_t significand = (br & significand_mask);
3211 int exponent = static_cast<int>((br & exponent_mask<double>()) >>
3212 num_significand_bits<double>());
3213
3214 if (exponent != 0) { // Check if normal.
3215 exponent -= exponent_bias<double>() + num_significand_bits<double>();
3216 significand |=
3217 (static_cast<uint64_t>(1) << num_significand_bits<double>());
3218 significand <<= 1;
3219 } else {
3220 // Normalize subnormal inputs.
3221 FMT_ASSERT(significand != 0, "zeros should not appear here");
3222 int shift = countl_zero(significand);
3223 FMT_ASSERT(shift >= num_bits<uint64_t>() - num_significand_bits<double>(),
3224 "");
3225 shift -= (num_bits<uint64_t>() - num_significand_bits<double>() - 2);
3226 exponent = (std::numeric_limits<double>::min_exponent -
3227 num_significand_bits<double>()) -

Callers

nothing calls this directly

Calls 15

convert_floatFunction · 0.85
to_unsignedFunction · 0.85
fill_nFunction · 0.85
is_constant_evaluatedFunction · 0.85
countl_zeroFunction · 0.85
floor_log10_pow2Function · 0.85
floor_log2_pow10Function · 0.85
umul192_upper128Function · 0.85
get_cached_powerFunction · 0.85
umul128_upper64Function · 0.85
min_ofFunction · 0.85
write2digitsFunction · 0.85

Tested by

no test coverage detected