diff --git a/include/fast_float/digit_comparison.h b/include/fast_float/digit_comparison.h index ffac7fd..6229653 100644 --- a/include/fast_float/digit_comparison.h +++ b/include/fast_float/digit_comparison.h @@ -40,7 +40,7 @@ constexpr static uint64_t powers_of_ten_uint64[] = {1UL, // to slow down performance for faster algorithms, and this is still fast. template fastfloat_really_inline FASTFLOAT_CONSTEXPR14 int16_t -scientific_exponent(const parsed_number_string_t &num) noexcept { +scientific_exponent(parsed_number_string_t const &num) noexcept { uint64_t mantissa = num.mantissa; int16_t exponent = num.exponent; while (mantissa >= 10000) { @@ -61,7 +61,7 @@ scientific_exponent(const parsed_number_string_t &num) noexcept { // this converts a native floating-point number to an extended-precision float. template fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa -to_extended(T value) noexcept { +to_extended(T const &value) noexcept { using equiv_uint = equiv_uint_t; constexpr equiv_uint exponent_mask = binary_format::exponent_mask(); constexpr equiv_uint mantissa_mask = binary_format::mantissa_mask(); @@ -96,7 +96,7 @@ to_extended(T value) noexcept { // halfway between b and b+u. template fastfloat_really_inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa -to_extended_halfway(T value) noexcept { +to_extended_halfway(T const &value) noexcept { adjusted_mantissa am = to_extended(value); am.mantissa <<= 1; am.mantissa += 1; @@ -341,17 +341,17 @@ parse_mantissa(bigint &result, const parsed_number_string_t &num, } template -inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa -positive_digit_comp(bigint &bigmant, int32_t exponent) noexcept { +inline FASTFLOAT_CONSTEXPR20 void +positive_digit_comp(bigint &bigmant, adjusted_mantissa &am, + int32_t const exponent) noexcept { FASTFLOAT_ASSERT(bigmant.pow10(uint32_t(exponent))); - adjusted_mantissa answer; bool truncated; - answer.mantissa = bigmant.hi64(truncated); - int bias = binary_format::mantissa_explicit_bits() - + am.mantissa = bigmant.hi64(truncated); + int32_t bias = binary_format::mantissa_explicit_bits() - binary_format::minimum_exponent(); - answer.power2 = bigmant.bit_length() - 64 + bias; + am.power2 = bigmant.bit_length() - 64 + bias; - round(answer, [truncated](adjusted_mantissa &a, int32_t shift) { + round(am, [truncated](adjusted_mantissa &a, int32_t shift) { round_nearest_tie_even( a, shift, [truncated](bool is_odd, bool is_halfway, bool is_above) -> bool { @@ -359,8 +359,6 @@ positive_digit_comp(bigint &bigmant, int32_t exponent) noexcept { (is_odd && is_halfway); }); }); - - return answer; } // the scaling here is quite simple: we have, for the real digits `m * 10^e`, @@ -369,24 +367,26 @@ positive_digit_comp(bigint &bigmant, int32_t exponent) noexcept { // we then need to scale by `2^(f- e)`, and then the two significant digits // are of the same magnitude. template -inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa -negative_digit_comp(bigint &bigmant, const adjusted_mantissa am, - const int32_t exponent) noexcept { +inline FASTFLOAT_CONSTEXPR20 void +negative_digit_comp(bigint &bigmant, adjusted_mantissa &am, + int32_t const exponent) noexcept { bigint &real_digits = bigmant; const int32_t &real_exp = exponent; - // get the value of `b`, rounded down, and get a bigint representation of b+h - adjusted_mantissa am_b = am; - // gcc7 buf: use a lambda to remove the noexcept qualifier bug with - // -Wnoexcept-type. - round(am_b, - [](adjusted_mantissa &a, int32_t shift) { round_down(a, shift); }); T b; - to_float( + { + // get the value of `b`, rounded down, and get a bigint representation of b+h + adjusted_mantissa am_b = am; + // gcc7 bug: use a lambda to remove the noexcept qualifier bug with + // -Wnoexcept-type. + round(am_b, + [](adjusted_mantissa &a, int32_t shift) { round_down(a, shift); }); + to_float( #ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN - false, + false, #endif - am_b, b); + am_b, b); + } adjusted_mantissa theor = to_extended_halfway(b); bigint theor_digits(theor.mantissa); int32_t theor_exp = theor.power2; @@ -405,8 +405,7 @@ negative_digit_comp(bigint &bigmant, const adjusted_mantissa am, // compare digits, and use it to director rounding int ord = real_digits.compare(theor_digits); - adjusted_mantissa answer = am; - round(answer, [ord](adjusted_mantissa &a, int32_t shift) { + round(am, [ord](adjusted_mantissa &a, int32_t shift) { round_nearest_tie_even( a, shift, [ord](bool is_odd, bool _, bool __) -> bool { (void)_; // not needed, since we've done our comparison @@ -420,8 +419,6 @@ negative_digit_comp(bigint &bigmant, const adjusted_mantissa am, } }); }); - - return answer; } // parse the significant digits as a big integer to unambiguously round the @@ -438,8 +435,8 @@ negative_digit_comp(bigint &bigmant, const adjusted_mantissa am, // the actual digits. we then compare the big integer representations // of both, and use that to direct rounding. template -inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa digit_comp( - const parsed_number_string_t &num, adjusted_mantissa &am) noexcept { +inline FASTFLOAT_CONSTEXPR20 void digit_comp( + parsed_number_string_t const &num, adjusted_mantissa &am) noexcept { // remove the invalid exponent bias am.power2 -= invalid_am_bias; @@ -451,9 +448,9 @@ inline FASTFLOAT_CONSTEXPR20 adjusted_mantissa digit_comp( // can't underflow, since digits is at most max_digits. int16_t exponent = sci_exp + 1 - digits; if (exponent >= 0) { - return positive_digit_comp(bigmant, exponent); + positive_digit_comp(bigmant, am, exponent); } else { - return negative_digit_comp(bigmant, am, exponent); + negative_digit_comp(bigmant, am, exponent); } } diff --git a/include/fast_float/float_common.h b/include/fast_float/float_common.h index adb56a3..5153b30 100644 --- a/include/fast_float/float_common.h +++ b/include/fast_float/float_common.h @@ -772,7 +772,7 @@ inline constexpr int binary_format::smallest_power_of_ten() { } template <> -inline constexpr unsigned int binary_format::max_digits() { +inline constexpr size_t binary_format::max_digits() { return 22; } #endif // __STDCPP_FLOAT16_T__ @@ -899,7 +899,7 @@ inline constexpr int binary_format::smallest_power_of_ten() { } template <> -inline constexpr unsigned int binary_format::max_digits() { +inline constexpr size_t binary_format::max_digits() { return 98; } #endif // __STDCPP_BFLOAT16_T__ @@ -1009,7 +1009,7 @@ fastfloat_really_inline FASTFLOAT_CONSTEXPR20 void to_float( #ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN bool const negative, #endif - adjusted_mantissa const am, T &value) noexcept { + adjusted_mantissa const &am, T &value) noexcept { using equiv_uint = equiv_uint_t; equiv_uint word = equiv_uint(am.mantissa); word = equiv_uint(word | equiv_uint(am.power2) diff --git a/include/fast_float/parse_number.h b/include/fast_float/parse_number.h index e5c08be..677a146 100644 --- a/include/fast_float/parse_number.h +++ b/include/fast_float/parse_number.h @@ -283,7 +283,7 @@ from_chars_advanced(parsed_number_string_t const &pns, T &value) noexcept { // and we have an invalid power (am.power2 < 0), then we need to go the long // way around again. This is very uncommon. if (am.power2 < 0) { - am = digit_comp(pns, am); + digit_comp(pns, am); } to_float( #ifndef FASTFLOAT_ONLY_POSITIVE_C_NUMBER_WO_INF_NAN