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

Method format_hexfloat

include/fmt/format.h:2920–2993  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

2918// Formats a floating-point number using the hexfloat format.
2919template <typename Float, FMT_ENABLE_IF(!is_double_double<Float>::value)>
2920FMT_CONSTEXPR20 void format_hexfloat(Float value, int precision, float_specs specs, buffer<char>& buf) {
2921 // float is passed as double to reduce the number of instantiations and to
2922 // simplify implementation.
2923 static_assert(!std::is_same<Float, float>::value, "");
2924
2925 using info = dragonbox::float_info<Float>;
2926
2927 // Assume Float is in the format [sign][exponent][significand].
2928 using carrier_uint = typename info::carrier_uint;
2929
2930 constexpr auto num_float_significand_bits = detail::num_significand_bits<Float>();
2931
2932 basic_fp<carrier_uint> f(value);
2933 f.e += num_float_significand_bits;
2934 if (!has_implicit_bit<Float>()) --f.e;
2935
2936 constexpr auto num_fraction_bits = num_float_significand_bits + (has_implicit_bit<Float>() ? 1 : 0);
2937 constexpr auto num_xdigits = (num_fraction_bits + 3) / 4;
2938
2939 constexpr auto leading_shift = ((num_xdigits - 1) * 4);
2940 const auto leading_mask = carrier_uint(0xF) << leading_shift;
2941 const auto leading_xdigit = static_cast<uint32_t>((f.f & leading_mask) >> leading_shift);
2942 if (leading_xdigit > 1) f.e -= (32 - countl_zero(leading_xdigit) - 1);
2943
2944 int print_xdigits = num_xdigits - 1;
2945 if (precision >= 0 && print_xdigits > precision) {
2946 const int shift = ((print_xdigits - precision - 1) * 4);
2947 const auto mask = carrier_uint(0xF) << shift;
2948 const auto v = static_cast<uint32_t>((f.f & mask) >> shift);
2949
2950 if (v >= 8) {
2951 const auto inc = carrier_uint(1) << (shift + 4);
2952 f.f += inc;
2953 f.f &= ~(inc - 1);
2954 }
2955
2956 // Check long double overflow
2957 if (!has_implicit_bit<Float>()) {
2958 const auto implicit_bit = carrier_uint(1) << num_float_significand_bits;
2959 if ((f.f & implicit_bit) == implicit_bit) {
2960 f.f >>= 4;
2961 f.e += 4;
2962 }
2963 }
2964
2965 print_xdigits = precision;
2966 }
2967
2968 char xdigits[num_bits<carrier_uint>() / 4];
2969 detail::fill_n(xdigits, sizeof(xdigits), '0');
2970 format_uint<4>(xdigits, f.f, num_xdigits, specs.upper);
2971
2972 // Remove zero tail
2973 while (print_xdigits > 0 && xdigits[print_xdigits] == '0') --print_xdigits;
2974
2975 buf.push_back('0');
2976 buf.push_back(specs.upper ? 'X' : 'x');
2977 buf.push_back(xdigits[0]);

Callers

nothing calls this directly

Calls 6

countl_zeroFunction · 0.85
fill_nFunction · 0.85
appenderClass · 0.85
count_digitsFunction · 0.85
push_backMethod · 0.80
appendMethod · 0.45

Tested by

no test coverage detected