Fix truncate flag.

This commit is contained in:
Daniel Lemire 2021-01-11 11:22:00 -05:00
parent f7c84156d5
commit c5adf9e4a5
2 changed files with 27 additions and 9 deletions

View File

@ -249,6 +249,27 @@ fastfloat_really_inline decimal parse_decimal(const char *p, const char *pend) n
} }
answer.decimal_point = int32_t(first_after_period - p); answer.decimal_point = int32_t(first_after_period - p);
} }
// We want num_digits to be the number of significant digits, excluding
// leading *and* trailing zeros! Otherwise the truncated flag later is
// going to be misleading.
if(answer.num_digits > 0) {
// We potentially need the answer.num_digits > 0 guard because we
// prune leading zeros. So with answer.num_digits > 0, we know that
// we have at least one non-zero digit.
const char *preverse = p - 1;
int32_t trailing_zeros = 0;
while ((*preverse == '0') || (*preverse == '.')) {
if(*preverse == '0') { trailing_zeros++; };
--preverse;
}
answer.decimal_point += trailing_zeros;
answer.num_digits -= uint32_t(trailing_zeros);
answer.decimal_point += int32_t(answer.num_digits);
}
if(answer.num_digits > max_digits) {
answer.truncated = true;
answer.num_digits = max_digits;
}
if ((p != pend) && (('e' == *p) || ('E' == *p))) { if ((p != pend) && (('e' == *p) || ('E' == *p))) {
++p; ++p;
bool neg_exp = false; bool neg_exp = false;
@ -268,11 +289,6 @@ fastfloat_really_inline decimal parse_decimal(const char *p, const char *pend) n
} }
answer.decimal_point += (neg_exp ? -exp_number : exp_number); answer.decimal_point += (neg_exp ? -exp_number : exp_number);
} }
answer.decimal_point += int32_t(answer.num_digits);
if(answer.num_digits > max_digits) {
answer.truncated = true;
answer.num_digits = max_digits;
}
// In very rare cases, we may have fewer than 19 digits, we want to be able to reliably // In very rare cases, we may have fewer than 19 digits, we want to be able to reliably
// assume that all digits up to max_digit_without_overflow have been initialized. // assume that all digits up to max_digit_without_overflow have been initialized.
for(uint32_t i = answer.num_digits; i < max_digit_without_overflow; i++) { answer.digits[i] = 0; } for(uint32_t i = answer.num_digits; i < max_digit_without_overflow; i++) { answer.digits[i] = 0; }

View File

@ -294,10 +294,8 @@ TEST_CASE("64bit.inf") {
} }
TEST_CASE("64bit.general") { TEST_CASE("64bit.general") {
verify("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125", 0x1.2ced2f1aa2833p+0); verify("9007199254740993.0", 0x1p+53);
verify(append_zeros("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125",655), 0x1.2ced2f1aa2833p+0); verify(append_zeros("9007199254740993.0",1000), 0x1p+53);
verify(append_zeros("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125",656), 0x1.2ced2f1aa2833p+0);
verify(append_zeros("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125",1000), 0x1.2ced2f1aa2833p+0);
verify("10000000000000000000", 0x1.158e460913dp+63); verify("10000000000000000000", 0x1.158e460913dp+63);
verify("10000000000000000000000000000001000000000000", 0x1.cb2d6f618c879p+142); verify("10000000000000000000000000000001000000000000", 0x1.cb2d6f618c879p+142);
verify("10000000000000000000000000000000000000000001", 0x1.cb2d6f618c879p+142); verify("10000000000000000000000000000000000000000001", 0x1.cb2d6f618c879p+142);
@ -369,9 +367,13 @@ TEST_CASE("32bit.inf") {
TEST_CASE("32bit.general") { TEST_CASE("32bit.general") {
verify("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125", 0x1.2ced3p+0f); verify("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125", 0x1.2ced3p+0f);
verify("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125e-38", 0x1.fffff8p-127f);
verify(append_zeros("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125",655), 0x1.2ced3p+0f); verify(append_zeros("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125",655), 0x1.2ced3p+0f);
verify(append_zeros("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125",656), 0x1.2ced3p+0f); verify(append_zeros("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125",656), 0x1.2ced3p+0f);
verify(append_zeros("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125",1000), 0x1.2ced3p+0f); verify(append_zeros("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125",1000), 0x1.2ced3p+0f);
verify(append_zeros("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125",655) + "e-38", 0x1.fffff8p-127f);
verify(append_zeros("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125",656) + "e-38", 0x1.fffff8p-127f);
verify(append_zeros("1.1754941406275178592461758986628081843312458647327962400313859427181746759860647699724722770042717456817626953125",1000) + "e-38", 0x1.fffff8p-127f);
verify32(1.00000006e+09f); verify32(1.00000006e+09f);
verify32(1.4012984643e-45f); verify32(1.4012984643e-45f);
verify32(1.1754942107e-38f); verify32(1.1754942107e-38f);