mirror of
https://github.com/fastfloat/fast_float.git
synced 2025-12-07 01:06:48 +08:00
Merge pull request #20 from lemire/dlemire/issue19
Better handling of the trailing exponential
This commit is contained in:
commit
33c9d55ba8
@ -115,8 +115,8 @@ parsed_number_string parse_number_string(const char *p, const char *pend, chars_
|
|||||||
int32_t digit_count =
|
int32_t digit_count =
|
||||||
int32_t(p - start_digits - 1); // used later to guard against overflows
|
int32_t(p - start_digits - 1); // used later to guard against overflows
|
||||||
|
|
||||||
if ((p != pend) && (('e' == *p) || ('E' == *p))) {
|
if ((fmt & chars_format::scientific) && (p != pend) && (('e' == *p) || ('E' == *p))) {
|
||||||
if((fmt & chars_format::fixed) && !(fmt & chars_format::scientific)) { return answer; }
|
const char * location_of_e = p;
|
||||||
int64_t exp_number = 0; // exponential part
|
int64_t exp_number = 0; // exponential part
|
||||||
++p;
|
++p;
|
||||||
bool neg_exp = false;
|
bool neg_exp = false;
|
||||||
@ -127,17 +127,23 @@ parsed_number_string parse_number_string(const char *p, const char *pend, chars_
|
|||||||
++p;
|
++p;
|
||||||
}
|
}
|
||||||
if ((p == pend) || !is_integer(*p)) {
|
if ((p == pend) || !is_integer(*p)) {
|
||||||
return answer;
|
if(!(fmt & chars_format::fixed)) {
|
||||||
}
|
// We are in error.
|
||||||
while ((p != pend) && is_integer(*p)) {
|
return answer;
|
||||||
uint8_t digit = uint8_t(*p - '0');
|
|
||||||
if (exp_number < 0x10000) {
|
|
||||||
exp_number = 10 * exp_number + digit;
|
|
||||||
}
|
}
|
||||||
++p;
|
// Otherwise, we will be ignoring the 'e'.
|
||||||
|
} else {
|
||||||
|
while ((p != pend) && is_integer(*p)) {
|
||||||
|
uint8_t digit = uint8_t(*p - '0');
|
||||||
|
if (exp_number < 0x10000) {
|
||||||
|
exp_number = 10 * exp_number + digit;
|
||||||
|
}
|
||||||
|
++p;
|
||||||
|
}
|
||||||
|
exponent += (neg_exp ? -exp_number : exp_number);
|
||||||
}
|
}
|
||||||
exponent += (neg_exp ? -exp_number : exp_number);
|
|
||||||
} else {
|
} else {
|
||||||
|
// If it scientific and not fixed, we have to bail out.
|
||||||
if((fmt & chars_format::scientific) && !(fmt & chars_format::fixed)) { return answer; }
|
if((fmt & chars_format::scientific) && !(fmt & chars_format::fixed)) { return answer; }
|
||||||
}
|
}
|
||||||
answer.lastmatch = p;
|
answer.lastmatch = p;
|
||||||
|
|||||||
@ -63,6 +63,7 @@ from_chars_result parse_infnan(const char *first, const char *last, T &value) n
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
answer.ec = std::errc::invalid_argument;
|
answer.ec = std::errc::invalid_argument;
|
||||||
|
answer.ptr = first;
|
||||||
return answer;
|
return answer;
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@ -147,9 +147,42 @@ bool issue8() {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool check_behavior() {
|
||||||
|
const std::string input = "abc";
|
||||||
|
double result;
|
||||||
|
auto answer = fast_float::from_chars(input.data(), input.data()+input.size(), result);
|
||||||
|
if(answer.ec != std::errc()) {
|
||||||
|
std::cerr << "parsing failure as expected\n";
|
||||||
|
// specification says ptr should point at first
|
||||||
|
if(answer.ptr != input.data()) {
|
||||||
|
std::cerr << "If there is no pattern match, we should have ptr equals first\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
std::cout << "parsed the number " << result << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool issue19() {
|
||||||
|
const std::string input = "3.14e";
|
||||||
|
double result;
|
||||||
|
auto answer = fast_float::from_chars(input.data(), input.data()+input.size(), result);
|
||||||
|
if(answer.ec != std::errc()) {
|
||||||
|
std::cerr << "We want to parse up to 3.14\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
std::cout << "parsed the number " << result << std::endl;
|
||||||
|
if(answer.ptr != input.data() + 4) {
|
||||||
|
std::cout << "Parsed the number and stopped at the right character." << result << std::endl;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
|
Assert(issue19());
|
||||||
|
Assert(check_behavior());
|
||||||
std::cout << "======= 64 bits " << std::endl;
|
std::cout << "======= 64 bits " << std::endl;
|
||||||
Assert(basic_test_64bit("INF",std::numeric_limits<double>::infinity()));
|
Assert(basic_test_64bit("INF",std::numeric_limits<double>::infinity()));
|
||||||
Assert(basic_test_64bit("-INF",-std::numeric_limits<double>::infinity()));
|
Assert(basic_test_64bit("-INF",-std::numeric_limits<double>::infinity()));
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user