Formats a floating-point number using a variation of the Fixed-Precision Positive Floating-Point Printout ((FPP)^2) algorithm by Steele & White: https://fmt.dev/papers/p372-steele.pdf.
| 2934 | // Positive Floating-Point Printout ((FPP)^2) algorithm by Steele & White: |
| 2935 | // https://fmt.dev/papers/p372-steele.pdf. |
| 2936 | FMT_CONSTEXPR20 inline void format_dragon(basic_fp<uint128_t> value, |
| 2937 | unsigned flags, int num_digits, |
| 2938 | buffer<char>& buf, int& exp10) { |
| 2939 | bigint numerator; // 2 * R in (FPP)^2. |
| 2940 | bigint denominator; // 2 * S in (FPP)^2. |
| 2941 | // lower and upper are differences between value and corresponding boundaries. |
| 2942 | bigint lower; // (M^- in (FPP)^2). |
| 2943 | bigint upper_store; // upper's value if different from lower. |
| 2944 | bigint* upper = nullptr; // (M^+ in (FPP)^2). |
| 2945 | // Shift numerator and denominator by an extra bit or two (if lower boundary |
| 2946 | // is closer) to make lower and upper integers. This eliminates multiplication |
| 2947 | // by 2 during later computations. |
| 2948 | bool is_predecessor_closer = (flags & dragon::predecessor_closer) != 0; |
| 2949 | int shift = is_predecessor_closer ? 2 : 1; |
| 2950 | if (value.e >= 0) { |
| 2951 | numerator = value.f; |
| 2952 | numerator <<= value.e + shift; |
| 2953 | lower = 1; |
| 2954 | lower <<= value.e; |
| 2955 | if (is_predecessor_closer) { |
| 2956 | upper_store = 1; |
| 2957 | upper_store <<= value.e + 1; |
| 2958 | upper = &upper_store; |
| 2959 | } |
| 2960 | denominator.assign_pow10(exp10); |
| 2961 | denominator <<= shift; |
| 2962 | } else if (exp10 < 0) { |
| 2963 | numerator.assign_pow10(-exp10); |
| 2964 | lower.assign(numerator); |
| 2965 | if (is_predecessor_closer) { |
| 2966 | upper_store.assign(numerator); |
| 2967 | upper_store <<= 1; |
| 2968 | upper = &upper_store; |
| 2969 | } |
| 2970 | numerator *= value.f; |
| 2971 | numerator <<= shift; |
| 2972 | denominator = 1; |
| 2973 | denominator <<= shift - value.e; |
| 2974 | } else { |
| 2975 | numerator = value.f; |
| 2976 | numerator <<= shift; |
| 2977 | denominator.assign_pow10(exp10); |
| 2978 | denominator <<= shift - value.e; |
| 2979 | lower = 1; |
| 2980 | if (is_predecessor_closer) { |
| 2981 | upper_store = 1ULL << 1; |
| 2982 | upper = &upper_store; |
| 2983 | } |
| 2984 | } |
| 2985 | int even = static_cast<int>((value.f & 1) == 0); |
| 2986 | if (!upper) upper = &lower; |
| 2987 | bool shortest = num_digits < 0; |
| 2988 | if ((flags & dragon::fixup) != 0) { |
| 2989 | if (add_compare(numerator, *upper, denominator) + even <= 0) { |
| 2990 | --exp10; |
| 2991 | numerator *= 10; |
| 2992 | if (num_digits < 0) { |
| 2993 | lower *= 10; |
nothing calls this directly
no test coverage detected