diff --git a/src/from_chars.cpp b/src/from_chars.cpp index 2bcff201f..bbefa295a 100644 --- a/src/from_chars.cpp +++ b/src/from_chars.cpp @@ -98,7 +98,20 @@ decimal parse_decimal(const char *&p) noexcept { } answer.decimal_point = int32_t(first_after_period - p); } - + if(answer.num_digits > 0) { + const char *preverse = p - 1; + int32_t trailing_zeros = 0; + while ((*preverse == '0') || (*preverse == '.')) { + if(*preverse == '0') { trailing_zeros++; }; + --preverse; + } + answer.decimal_point += int32_t(answer.num_digits); + answer.num_digits -= uint32_t(trailing_zeros); + } + if(answer.num_digits > max_digits ) { + answer.num_digits = max_digits; + answer.truncated = true; + } if (('e' == *p) || ('E' == *p)) { ++p; bool neg_exp = false; @@ -118,11 +131,6 @@ decimal parse_decimal(const char *&p) noexcept { } answer.decimal_point += (neg_exp ? -exp_number : exp_number); } - answer.decimal_point += answer.num_digits; - if(answer.num_digits > max_digits ) { - answer.num_digits = max_digits; - answer.truncated = true; - } return answer; } diff --git a/tests/basictests.cpp b/tests/basictests.cpp index 4f07c376a..1bb2a321d 100644 --- a/tests/basictests.cpp +++ b/tests/basictests.cpp @@ -280,6 +280,12 @@ namespace number_tests { std::cout << std::dec; return true; } + bool truncated_borderline() { + std::cout << __func__ << std::endl; + std::string round_to_even = "9007199254740993.0"; + for(size_t i = 0; i < 1000; i++) { round_to_even += "0"; } + return basic_test_64bit(round_to_even,9007199254740992); + } bool specific_tests() { std::cout << __func__ << std::endl; @@ -299,7 +305,8 @@ namespace number_tests { } bool run() { - return specific_tests() && + return truncated_borderline() && + specific_tests() && ground_truth() && small_integers() && powers_of_two() && diff --git a/tests/random_string_number_tests.cpp b/tests/random_string_number_tests.cpp index 4736cf62e..127e84fd5 100644 --- a/tests/random_string_number_tests.cpp +++ b/tests/random_string_number_tests.cpp @@ -119,9 +119,9 @@ bool check_float(double result, const char *buf) { return false; } if (expected != result) { - fprintf(stderr, "parsed %.128e from \n", result); - fprintf(stderr, " %.32s whereas strtod gives\n", buf); - fprintf(stderr, " %.128e,", expected); + std::cerr << std::hexfloat << " parsed " << result << " from " + << buf << " whereas strtod gives " << expected << std::endl; + std::cerr << std::defaultfloat; return false; } return true;