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

Method format_hexfloat

include/fmt/format.h:3072–3149  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

3070// Formats a floating-point number using the hexfloat format.
3071template <typename Float, FMT_ENABLE_IF(!is_double_double<Float>::value)>
3072FMT_CONSTEXPR20 void format_hexfloat(Float value, format_specs specs,
3073 buffer<char>& buf) {
3074 // float is passed as double to reduce the number of instantiations and to
3075 // simplify implementation.
3076 static_assert(!std::is_same<Float, float>::value, "");
3077
3078 using info = dragonbox::float_info<Float>;
3079
3080 // Assume Float is in the format [sign][exponent][significand].
3081 using carrier_uint = typename info::carrier_uint;
3082
3083 const auto num_float_significand_bits = detail::num_significand_bits<Float>();
3084
3085 basic_fp<carrier_uint> f(value);
3086 f.e += num_float_significand_bits;
3087 if (!has_implicit_bit<Float>()) --f.e;
3088
3089 const auto num_fraction_bits =
3090 num_float_significand_bits + (has_implicit_bit<Float>() ? 1 : 0);
3091 const auto num_xdigits = (num_fraction_bits + 3) / 4;
3092
3093 const auto leading_shift = ((num_xdigits - 1) * 4);
3094 const auto leading_mask = carrier_uint(0xF) << leading_shift;
3095 const auto leading_xdigit =
3096 static_cast<uint32_t>((f.f & leading_mask) >> leading_shift);
3097 if (leading_xdigit > 1) f.e -= (32 - countl_zero(leading_xdigit) - 1);
3098
3099 int print_xdigits = num_xdigits - 1;
3100 if (specs.precision >= 0 && print_xdigits > specs.precision) {
3101 const int shift = ((print_xdigits - specs.precision - 1) * 4);
3102 const auto mask = carrier_uint(0xF) << shift;
3103 const auto v = static_cast<uint32_t>((f.f & mask) >> shift);
3104
3105 if (v >= 8) {
3106 const auto inc = carrier_uint(1) << (shift + 4);
3107 f.f += inc;
3108 f.f &= ~(inc - 1);
3109 }
3110
3111 // Check long double overflow
3112 if (!has_implicit_bit<Float>()) {
3113 const auto implicit_bit = carrier_uint(1) << num_float_significand_bits;
3114 if ((f.f & implicit_bit) == implicit_bit) {
3115 f.f >>= 4;
3116 f.e += 4;
3117 }
3118 }
3119
3120 print_xdigits = specs.precision;
3121 }
3122
3123 char xdigits[num_bits<carrier_uint>() / 4];
3124 detail::fill_n(xdigits, sizeof(xdigits), '0');
3125 format_base2e(4, xdigits, f.f, num_xdigits, specs.upper());
3126
3127 // Remove zero tail
3128 while (print_xdigits > 0 && xdigits[print_xdigits] == '0') --print_xdigits;
3129

Callers

nothing calls this directly

Calls 7

countl_zeroFunction · 0.85
fill_nFunction · 0.85
format_base2eFunction · 0.85
count_digitsFunction · 0.85
upperMethod · 0.80
altMethod · 0.80
push_backMethod · 0.45

Tested by

no test coverage detected