diff --git a/include/fast_float/ascii_number.h b/include/fast_float/ascii_number.h index f45be46..a6f1fae 100644 --- a/include/fast_float/ascii_number.h +++ b/include/fast_float/ascii_number.h @@ -275,10 +275,11 @@ decimal parse_decimal(const char *&p, const char *pend) noexcept { } while ((p != pend) && is_integer(*p)) { if (answer.num_digits + 1 < max_digits) { - answer.digits[answer.num_digits++] = uint8_t(*p - '0'); + answer.digits[answer.num_digits] = uint8_t(*p - '0'); } else { answer.truncated = true; } + answer.num_digits++; ++p; } answer.decimal_point = int32_t(first_after_period - p); diff --git a/tests/basictest.cpp b/tests/basictest.cpp index b234689..054cc71 100644 --- a/tests/basictest.cpp +++ b/tests/basictest.cpp @@ -96,16 +96,45 @@ bool basic_test_64bit(std::string vals, double val) { return false; } std::cout << std::hexfloat << result_value << " == " << val << std::endl; - std::cout << std::dec; return true; } -bool basic_test_64bit(double val) { +bool basiciss_test_64bit(double val) { std::string long_vals = to_long_string(val); std::string vals = to_string(val); return basic_test_64bit(long_vals, val) && basic_test_64bit(vals, val); } +bool issue8() { + const char* s = + "3." + "141592653589793238462643383279502884197169399375105820974944592307816406" + "286208998628034825342117067982148086513282306647093844609550582231725359" + "408128481117450284102701938521105559644622948954930381964428810975665933" + "446128475648233786783165271201909145648566923460348610454326648213393607" + "260249141273724587006606315588174881520920962829254091715364367892590360" + "011330530548820466521384146951941511609433057270365759591953092186117381" + "932611793105118548074462379962749567351885752724891227938183011949129833" + "673362440656643086021394946395224737190702179860943702770539217176293176" + "752384674818467669405132000568127145263560827785771342757789609173637178" + "721468440901224953430146549585371050792279689258923542019956112129021960" + "864034418159813629774771309960518707211349999998372978"; + for (int i = 0; i < 16; i++) { + // Parse all but the last i chars. We should still get 3.141ish. + double d = 0.0; + auto answer = fast_float::from_chars(s, s + strlen(s) - i, d); + if(answer.ec != std::errc()) { std::cerr << "parsing failure\n"; return false; } + if(d != 0x1.921fb54442d18p+1) { + printf("%.*s\n", int(strlen(s) - i), s); + std::cout << std::hexfloat << d << std::endl; + std::cout << std::defaultfloat << d << std::endl; + return false; + } + + } + return true; +} + int main() { @@ -140,14 +169,14 @@ int main() { Assert(basic_test_64bit("2e30000000000000000", std::numeric_limits::infinity())); Assert(basic_test_64bit("2e3000", std::numeric_limits::infinity())); Assert(basic_test_64bit("1.9e308", std::numeric_limits::infinity())); - Assert(basic_test_64bit(3e-324)); - Assert(basic_test_64bit(1.00000006e+09f)); - Assert(basic_test_64bit(4.9406564584124653e-324)); - Assert(basic_test_64bit(4.9406564584124654e-324)); - Assert(basic_test_64bit(2.2250738585072009e-308)); - Assert(basic_test_64bit(2.2250738585072014e-308)); - Assert(basic_test_64bit(1.7976931348623157e308)); - Assert(basic_test_64bit(1.7976931348623158e308)); + Assert(basic_test_64bit("3e-324", 0x0.0000000000001p-1022)); + Assert(basic_test_64bit("1.00000006e+09", 0x1.dcd651ep+29)); + Assert(basic_test_64bit("4.9406564584124653e-324", 0x0.0000000000001p-1022)); + Assert(basic_test_64bit("4.9406564584124654e-324", 0x0.0000000000001p-1022)); + Assert(basic_test_64bit("2.2250738585072009e-308", 0x0.fffffffffffffp-1022)); + Assert(basic_test_64bit("2.2250738585072014e-308", 0x1p-1022)); + Assert(basic_test_64bit("1.7976931348623157e308", 0x1.fffffffffffffp+1023)); + Assert(basic_test_64bit("1.7976931348623158e308", 0x1.fffffffffffffp+1023)); Assert(basic_test_64bit("4503599627370496.5", 4503599627370496.5)); Assert(basic_test_64bit("4503599627475352.5", 4503599627475352.5)); Assert(basic_test_64bit("4503599627475353.5", 4503599627475353.5)); @@ -229,6 +258,8 @@ int main() { Assert(basic_test_32bit("0.00000000000000000000000000000000000001175494210692441075487029444849287348827052428745893333857174530571588870475618904265502351336181163787841796875", 0.00000000000000000000000000000000000001175494210692441075487029444849287348827052428745893333857174530571588870475618904265502351336181163787841796875)); std::cout << std::endl; + Assert(issue8()); + std::cout << "All ok" << std::endl; return EXIT_SUCCESS; }