We need to update some of our exhaustive tests to the new API

This commit is contained in:
Daniel Lemire 2023-04-02 17:43:17 -04:00
parent 843fb97064
commit ca43e6722e
21 changed files with 81 additions and 53 deletions

View File

@ -22,4 +22,4 @@ jobs:
cd build20 && cd build20 &&
CXX=clang++-14 cmake -DFASTFLOAT_CONSTEXPR_TESTS=ON -DCMAKE_CXX_STANDARD=20 -DFASTFLOAT_TEST=ON .. && CXX=clang++-14 cmake -DFASTFLOAT_CONSTEXPR_TESTS=ON -DCMAKE_CXX_STANDARD=20 -DFASTFLOAT_TEST=ON .. &&
cmake --build . && cmake --build . &&
ctest --output-on-failure ctest --output-on-failure

View File

@ -20,4 +20,4 @@ jobs:
cd build20 && cd build20 &&
CXX=g++-12 CXXFLAGS=-Werror cmake -DFASTFLOAT_CONSTEXPR_TESTS=ON -DCMAKE_CXX_STANDARD=20 -DFASTFLOAT_TEST=ON .. && CXX=g++-12 CXXFLAGS=-Werror cmake -DFASTFLOAT_CONSTEXPR_TESTS=ON -DCMAKE_CXX_STANDARD=20 -DFASTFLOAT_TEST=ON .. &&
cmake --build . && cmake --build . &&
ctest --output-on-failure ctest --output-on-failure

View File

@ -13,4 +13,4 @@ jobs:
cd build && cd build &&
cmake -DFASTFLOAT_TEST=ON .. && cmake -DFASTFLOAT_TEST=ON .. &&
cmake --build . && cmake --build . &&
ctest --output-on-failure ctest --output-on-failure

View File

@ -189,11 +189,11 @@ It can parse random floating-point numbers at a speed of 1 GB/s on some systems.
$ ./build/benchmarks/benchmark $ ./build/benchmarks/benchmark
# parsing random integers in the range [0,1) # parsing random integers in the range [0,1)
volume = 2.09808 MB volume = 2.09808 MB
netlib : 271.18 MB/s (+/- 1.2 %) 12.93 Mfloat/s netlib : 271.18 MB/s (+/- 1.2 %) 12.93 Mfloat/s
doubleconversion : 225.35 MB/s (+/- 1.2 %) 10.74 Mfloat/s doubleconversion : 225.35 MB/s (+/- 1.2 %) 10.74 Mfloat/s
strtod : 190.94 MB/s (+/- 1.6 %) 9.10 Mfloat/s strtod : 190.94 MB/s (+/- 1.6 %) 9.10 Mfloat/s
abseil : 430.45 MB/s (+/- 2.2 %) 20.52 Mfloat/s abseil : 430.45 MB/s (+/- 2.2 %) 20.52 Mfloat/s
fastfloat : 1042.38 MB/s (+/- 9.9 %) 49.68 Mfloat/s fastfloat : 1042.38 MB/s (+/- 9.9 %) 49.68 Mfloat/s
``` ```
See https://github.com/lemire/simple_fastfloat_benchmark for our benchmarking code. See https://github.com/lemire/simple_fastfloat_benchmark for our benchmarking code.

View File

@ -48,9 +48,9 @@ namespace detail {
* where * where
* p = log(5**q)/log(2) = q * log(5)/log(2) * p = log(5**q)/log(2) = q * log(5)/log(2)
* *
* For negative values of q in (-400,0), we have that * For negative values of q in (-400,0), we have that
* f = (((152170 + 65536) * q ) >> 16); * f = (((152170 + 65536) * q ) >> 16);
* is equal to * is equal to
* -ceil(p) + q * -ceil(p) + q
* where * where
* p = log(5**-q)/log(2) = -q * log(5)/log(2) * p = log(5**-q)/log(2) = -q * log(5)/log(2)

View File

@ -31,7 +31,7 @@ for filename in ['LICENSE-MIT', 'LICENSE-APACHE']:
processed_files[filename] = text processed_files[filename] = text
# code # code
for filename in [ 'constexpr_feature_detect.h', 'fast_float.h', 'float_common.h', 'ascii_number.h', for filename in [ 'constexpr_feature_detect.h', 'fast_float.h', 'float_common.h', 'ascii_number.h',
'fast_table.h', 'decimal_to_binary.h', 'bigint.h', 'fast_table.h', 'decimal_to_binary.h', 'bigint.h',
'ascii_number.h', 'digit_comparison.h', 'parse_number.h']: 'ascii_number.h', 'digit_comparison.h', 'parse_number.h']:
with open('include/fast_float/' + filename, encoding='utf8') as f: with open('include/fast_float/' + filename, encoding='utf8') as f:
@ -73,10 +73,10 @@ def license_content(license_arg):
return result return result
text = ''.join([ text = ''.join([
processed_files['AUTHORS'], processed_files['CONTRIBUTORS'], processed_files['AUTHORS'], processed_files['CONTRIBUTORS'],
*license_content(args.license), *license_content(args.license),
processed_files['constexpr_feature_detect.h'], processed_files['constexpr_feature_detect.h'],
processed_files['fast_float.h'], processed_files['float_common.h'], processed_files['fast_float.h'], processed_files['float_common.h'],
processed_files['ascii_number.h'], processed_files['fast_table.h'], processed_files['ascii_number.h'], processed_files['fast_table.h'],
processed_files['decimal_to_binary.h'], processed_files['bigint.h'], processed_files['decimal_to_binary.h'], processed_files['bigint.h'],
processed_files['ascii_number.h'], processed_files['digit_comparison.h'], processed_files['ascii_number.h'], processed_files['digit_comparison.h'],

View File

@ -1,12 +1,12 @@
# #
# Reference : # Reference :
# Noble Mushtak and Daniel Lemire, Fast Number Parsing Without Fallback (to appear) # Noble Mushtak and Daniel Lemire, Fast Number Parsing Without Fallback (to appear)
# #
all_tqs = [] all_tqs = []
# Generates all possible values of T[q] # Generates all possible values of T[q]
# Appendix B of Number parsing at a gigabyte per second. # Appendix B of Number parsing at a gigabyte per second.
# Software: Practice and Experience 2021;51(8):17001727. # Software: Practice and Experience 2021;51(8):17001727.
for q in range(-342, -27): for q in range(-342, -27):
power5 = 5**-q power5 = 5**-q
@ -44,9 +44,9 @@ def continued_fraction(numer, denom):
numer, denom = denom, rem numer, denom = denom, rem
return cf return cf
# Given a continued fraction [a0; a1, a2, ..., an], returns # Given a continued fraction [a0; a1, a2, ..., an], returns
# all the convergents of that continued fraction # all the convergents of that continued fraction
# as pairs of the form (numer, denom), where numer/denom is # as pairs of the form (numer, denom), where numer/denom is
# a convergent of the continued fraction in simple form. # a convergent of the continued fraction in simple form.
def convergents(cf): def convergents(cf):
p_n_minus_2 = 0 p_n_minus_2 = 0

View File

@ -3,7 +3,7 @@
#include <iostream> #include <iostream>
#include <string> #include <string>
#include <system_error> #include <system_error>
int main() { int main() {
const std::string input = "3,1416 xyz "; const std::string input = "3,1416 xyz ";
double result; double result;

View File

@ -30,7 +30,10 @@ void allvalues() {
const char *string_end = to_string(v, buffer); const char *string_end = to_string(v, buffer);
float result_value; float result_value;
auto result = fast_float::from_chars(buffer, string_end, result_value); auto result = fast_float::from_chars(buffer, string_end, result_value);
if (result.ec != std::errc()) { // Starting with version 4.0 for fast_float, we return result_out_of_range if the
// value is either too small (too close to zero) or too large (effectively infinity).
// So std::errc::result_out_of_range is normal for well-formed input strings.
if (result.ec != std::errc() && result.ec != std::errc::result_out_of_range) {
std::cerr << "parsing error ? " << buffer << std::endl; std::cerr << "parsing error ? " << buffer << std::endl;
abort(); abort();
} }
@ -46,7 +49,7 @@ void allvalues() {
} else if (result_value != v) { } else if (result_value != v) {
std::cerr << "no match ? " << buffer << std::endl; std::cerr << "no match ? " << buffer << std::endl;
std::cout << "started with " << std::hexfloat << v << std::endl; std::cout << "started with " << std::hexfloat << v << std::endl;
std::cout << "got back " << std::hexfloat << result_value << std::endl; std::cout << "got back " << std::hexfloat << result_value << std::endl;
std::cout << std::dec; std::cout << std::dec;
abort(); abort();
} }

View File

@ -21,7 +21,7 @@ bool basic_test_64bit(std::string vals, double val) {
double result_value; double result_value;
auto result = fast_float::from_chars(vals.data(), vals.data() + vals.size(), auto result = fast_float::from_chars(vals.data(), vals.data() + vals.size(),
result_value); result_value);
if (result.ec != std::errc()) { if (result.ec != std::errc() && result.ec != std::errc::result_out_of_range) {
std::cerr << " I could not parse " << vals << std::endl; std::cerr << " I could not parse " << vals << std::endl;
return false; return false;
} }
@ -30,11 +30,11 @@ bool basic_test_64bit(std::string vals, double val) {
std::cerr << vals << std::endl; std::cerr << vals << std::endl;
std::cerr << "not nan" << result_value << std::endl; std::cerr << "not nan" << result_value << std::endl;
return false; return false;
} }
} else if(copysign(1,result_value) != copysign(1,val)) { } else if(copysign(1,result_value) != copysign(1,val)) {
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << val std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << val
<< std::endl; << std::endl;
return false; return false;
} else if (result_value != val) { } else if (result_value != val) {
std::cerr << vals << std::endl; std::cerr << vals << std::endl;
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << val std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << val

View File

@ -8,7 +8,7 @@
#include <limits> #include <limits>
#include <stdexcept> #include <stdexcept>
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__)
// Anything at all that is related to cygwin, msys and so forth will // Anything at all that is related to cygwin, msys and so forth will
// always use this fallback because we cannot rely on it behaving as normal // always use this fallback because we cannot rely on it behaving as normal
// gcc. // gcc.
@ -73,7 +73,7 @@ bool allvalues() {
} }
uint32_t word = uint32_t(w); uint32_t word = uint32_t(w);
memcpy(&v, &word, sizeof(v)); memcpy(&v, &word, sizeof(v));
if(std::isfinite(v)) { if(std::isfinite(v)) {
float nextf = std::nextafterf(v, INFINITY); float nextf = std::nextafterf(v, INFINITY);
if(copysign(1,v) != copysign(1,nextf)) { continue; } if(copysign(1,v) != copysign(1,nextf)) { continue; }
if(!std::isfinite(nextf)) { continue; } if(!std::isfinite(nextf)) { continue; }
@ -90,7 +90,10 @@ bool allvalues() {
float result_value; float result_value;
auto result = fast_float::from_chars(buffer, string_end, result_value); auto result = fast_float::from_chars(buffer, string_end, result_value);
if (result.ec != std::errc()) { // Starting with version 4.0 for fast_float, we return result_out_of_range if the
// value is either too small (too close to zero) or too large (effectively infinity).
// So std::errc::result_out_of_range is normal for well-formed input strings.
if (result.ec != std::errc() && result.ec != std::errc::result_out_of_range) {
std::cerr << "parsing error ? " << buffer << std::endl; std::cerr << "parsing error ? " << buffer << std::endl;
return false; return false;
} }
@ -120,7 +123,7 @@ bool allvalues() {
std::cerr << "expected_midv " << std::hexfloat << expected_midv << std::endl; std::cerr << "expected_midv " << std::hexfloat << expected_midv << std::endl;
std::cout << "started with " << std::hexfloat << midv << std::endl; std::cout << "started with " << std::hexfloat << midv << std::endl;
std::cout << "round down to " << std::hexfloat << str_answer << std::endl; std::cout << "round down to " << std::hexfloat << str_answer << std::endl;
std::cout << "got back " << std::hexfloat << result_value << std::endl; std::cout << "got back " << std::hexfloat << result_value << std::endl;
std::cout << std::dec; std::cout << std::dec;
return false; return false;
} }
@ -133,7 +136,7 @@ bool allvalues() {
inline void Assert(bool Assertion) { inline void Assert(bool Assertion) {
#if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun) #if defined(__CYGWIN__) || defined(__MINGW32__) || defined(__MINGW64__) || defined(sun) || defined(__sun)
if (!Assertion) { std::cerr << "Omitting hard failure on msys/cygwin/sun systems."; } if (!Assertion) { std::cerr << "Omitting hard failure on msys/cygwin/sun systems."; }
#else #else
if (!Assertion) { throw std::runtime_error("bug"); } if (!Assertion) { throw std::runtime_error("bug"); }
#endif #endif
} }

View File

@ -14,7 +14,7 @@ find_package(FastFloat REQUIRED)
file(WRITE main.cpp " file(WRITE main.cpp "
#include \"fast_float/fast_float.h\" #include \"fast_float/fast_float.h\"
#include <iostream> #include <iostream>
int main() { int main() {
const std::string input = \"3.1416 xyz \"; const std::string input = \"3.1416 xyz \";
double result; double result;

View File

@ -29,7 +29,10 @@ void allvalues() {
const char *string_end = to_string(v, buffer); const char *string_end = to_string(v, buffer);
float result_value; float result_value;
auto result = fast_float::from_chars(buffer, string_end, result_value); auto result = fast_float::from_chars(buffer, string_end, result_value);
if (result.ec != std::errc()) { // Starting with version 4.0 for fast_float, we return result_out_of_range if the
// value is either too small (too close to zero) or too large (effectively infinity).
// So std::errc::result_out_of_range is normal for well-formed input strings.
if (result.ec != std::errc() && result.ec != std::errc::result_out_of_range) {
std::cerr << "parsing error ? " << buffer << std::endl; std::cerr << "parsing error ? " << buffer << std::endl;
abort(); abort();
} }
@ -46,7 +49,7 @@ void allvalues() {
} else if (result_value != v) { } else if (result_value != v) {
std::cerr << "no match ? " << buffer << " got " << result_value << " expected " << v << std::endl; std::cerr << "no match ? " << buffer << " got " << result_value << " expected " << v << std::endl;
std::cout << "started with " << std::hexfloat << v << std::endl; std::cout << "started with " << std::hexfloat << v << std::endl;
std::cout << "got back " << std::hexfloat << result_value << std::endl; std::cout << "got back " << std::hexfloat << result_value << std::endl;
std::cout << std::dec; std::cout << std::dec;
abort(); abort();
} }

View File

@ -28,7 +28,10 @@ void all_32bit_values() {
const char *string_end = to_string(v, buffer); const char *string_end = to_string(v, buffer);
double result_value; double result_value;
auto result = fast_float::from_chars(buffer, string_end, result_value); auto result = fast_float::from_chars(buffer, string_end, result_value);
if (result.ec != std::errc()) { // Starting with version 4.0 for fast_float, we return result_out_of_range if the
// value is either too small (too close to zero) or too large (effectively infinity).
// So std::errc::result_out_of_range is normal for well-formed input strings.
if (result.ec != std::errc() && result.ec != std::errc::result_out_of_range) {
std::cerr << "parsing error ? " << buffer << std::endl; std::cerr << "parsing error ? " << buffer << std::endl;
abort(); abort();
} }
@ -49,7 +52,7 @@ void all_32bit_values() {
} else if (result_value != v) { } else if (result_value != v) {
std::cerr << "no match ? " << buffer << std::endl; std::cerr << "no match ? " << buffer << std::endl;
std::cout << "started with " << std::hexfloat << v << std::endl; std::cout << "started with " << std::hexfloat << v << std::endl;
std::cout << "got back " << std::hexfloat << result_value << std::endl; std::cout << "got back " << std::hexfloat << result_value << std::endl;
std::cout << std::dec; std::cout << std::dec;
abort(); abort();
} }

View File

@ -27,9 +27,9 @@ static fast_float::value128 g_lehmer64_state;
* Society 68.225 (1999): 249-260. * Society 68.225 (1999): 249-260.
*/ */
static inline void lehmer64_seed(uint64_t seed) { static inline void lehmer64_seed(uint64_t seed) {
g_lehmer64_state.high = 0; g_lehmer64_state.high = 0;
g_lehmer64_state.low = seed; g_lehmer64_state.low = seed;
} }
static inline uint64_t lehmer64() { static inline uint64_t lehmer64() {
@ -56,7 +56,10 @@ void random_values(size_t N) {
const char *string_end = to_string(v, buffer); const char *string_end = to_string(v, buffer);
double result_value; double result_value;
auto result = fast_float::from_chars(buffer, string_end, result_value); auto result = fast_float::from_chars(buffer, string_end, result_value);
if (result.ec != std::errc()) { // Starting with version 4.0 for fast_float, we return result_out_of_range if the
// value is either too small (too close to zero) or too large (effectively infinity).
// So std::errc::result_out_of_range is normal for well-formed input strings.
if (result.ec != std::errc() && result.ec != std::errc::result_out_of_range) {
std::cerr << "parsing error ? " << buffer << std::endl; std::cerr << "parsing error ? " << buffer << std::endl;
errors++; errors++;
if (errors > 10) { if (errors > 10) {
@ -80,7 +83,7 @@ void random_values(size_t N) {
} else if (result_value != v) { } else if (result_value != v) {
std::cerr << "no match ? '" << buffer << "'" << std::endl; std::cerr << "no match ? '" << buffer << "'" << std::endl;
std::cout << "started with " << std::hexfloat << v << std::endl; std::cout << "started with " << std::hexfloat << v << std::endl;
std::cout << "got back " << std::hexfloat << result_value << std::endl; std::cout << "got back " << std::hexfloat << result_value << std::endl;
std::cout << std::dec; std::cout << std::dec;
errors++; errors++;
if (errors > 10) { if (errors > 10) {

View File

@ -22,7 +22,7 @@ bool test() {
while((begin < end) && (std::isspace(*begin))) { begin++; } while((begin < end) && (std::isspace(*begin))) { begin++; }
auto result = fast_float::from_chars(begin, end, auto result = fast_float::from_chars(begin, end,
result_value); result_value);
if (result.ec != std::errc()) { if (result.ec != std::errc() && result.ec != std::errc::result_out_of_range) {
printf("parsing %.*s\n", int(end - begin), begin); printf("parsing %.*s\n", int(end - begin), begin);
std::cerr << " I could not parse " << std::endl; std::cerr << " I could not parse " << std::endl;
return false; return false;
@ -40,7 +40,7 @@ bool test() {
} }
if(begin != end) { if(begin != end) {
std::cerr << " bad ending " << std::endl; std::cerr << " bad ending " << std::endl;
return false; return false;
} }
return true; return true;
} }

View File

@ -105,7 +105,7 @@ bool tester() {
double result_value; double result_value;
auto result = auto result =
fast_float::from_chars(to_be_parsed.data(), to_be_parsed.data() + to_be_parsed.size(), result_value); fast_float::from_chars(to_be_parsed.data(), to_be_parsed.data() + to_be_parsed.size(), result_value);
if (result.ec != std::errc()) { if (result.ec != std::errc() && result.ec != std::errc::result_out_of_range) {
std::cout << to_be_parsed << std::endl; std::cout << to_be_parsed << std::endl;
std::cerr << " I could not parse " << std::endl; std::cerr << " I could not parse " << std::endl;
return false; return false;

View File

@ -29,9 +29,9 @@ static fast_float::value128 g_lehmer64_state;
* Society 68.225 (1999): 249-260. * Society 68.225 (1999): 249-260.
*/ */
static inline void lehmer64_seed(uint64_t seed) { static inline void lehmer64_seed(uint64_t seed) {
g_lehmer64_state.high = 0; g_lehmer64_state.high = 0;
g_lehmer64_state.low = seed; g_lehmer64_state.low = seed;
} }
static inline uint64_t lehmer64() { static inline uint64_t lehmer64() {
@ -59,7 +59,10 @@ void random_values(size_t N) {
const char *string_end = to_string(v, buffer); const char *string_end = to_string(v, buffer);
double result_value; double result_value;
auto result = fast_float::from_chars(buffer, string_end, result_value); auto result = fast_float::from_chars(buffer, string_end, result_value);
if (result.ec != std::errc()) { // Starting with version 4.0 for fast_float, we return result_out_of_range if the
// value is either too small (too close to zero) or too large (effectively infinity).
// So std::errc::result_out_of_range is normal for well-formed input strings.
if (result.ec != std::errc() && result.ec != std::errc::result_out_of_range) {
std::cerr << "parsing error ? " << buffer << std::endl; std::cerr << "parsing error ? " << buffer << std::endl;
errors++; errors++;
if (errors > 10) { if (errors > 10) {
@ -83,7 +86,7 @@ void random_values(size_t N) {
} else if (result_value != v) { } else if (result_value != v) {
std::cerr << "no match ? " << buffer << std::endl; std::cerr << "no match ? " << buffer << std::endl;
std::cout << "started with " << std::hexfloat << v << std::endl; std::cout << "started with " << std::hexfloat << v << std::endl;
std::cout << "got back " << std::hexfloat << result_value << std::endl; std::cout << "got back " << std::hexfloat << result_value << std::endl;
std::cout << std::dec; std::cout << std::dec;
errors++; errors++;
if (errors > 10) { if (errors > 10) {

View File

@ -101,7 +101,12 @@ size_t build_random_string(RandomEngine &rand, char *buffer) {
if (i == size_t(location_of_decimal_separator)) { if (i == size_t(location_of_decimal_separator)) {
buffer[pos++] = '.'; buffer[pos++] = '.';
} }
buffer[pos++] = char(rand.next_digit() + '0'); buffer[pos] = char(rand.next_digit() + '0');
// We can have a leading zero only if location_of_decimal_separator = 1.
while(i == 0 && 1 != size_t(location_of_decimal_separator) && buffer[pos] == '0') {
buffer[pos] = char(rand.next_digit() + '0');
}
pos++;
} }
if (rand.next_bool()) { if (rand.next_bool()) {
if (rand.next_bool()) { if (rand.next_bool()) {
@ -178,7 +183,7 @@ bool tester(uint64_t seed, size_t volume) {
double result_value; double result_value;
auto result = auto result =
fast_float::from_chars(buffer, buffer + length, result_value); fast_float::from_chars(buffer, buffer + length, result_value);
if (result.ec != std::errc()) { if (result.ec != std::errc() && result.ec != std::errc::result_out_of_range) {
printf("parsing %.*s\n", int(length), buffer); printf("parsing %.*s\n", int(length), buffer);
std::cerr << " I could not parse " << std::endl; std::cerr << " I could not parse " << std::endl;
return false; return false;
@ -201,7 +206,7 @@ bool tester(uint64_t seed, size_t volume) {
float result_value; float result_value;
auto result = auto result =
fast_float::from_chars(buffer, buffer + length, result_value); fast_float::from_chars(buffer, buffer + length, result_value);
if (result.ec != std::errc()) { if (result.ec != std::errc() && result.ec != std::errc::result_out_of_range) {
printf("parsing %.*s\n", int(length), buffer); printf("parsing %.*s\n", int(length), buffer);
std::cerr << " I could not parse " << std::endl; std::cerr << " I could not parse " << std::endl;
return false; return false;

View File

@ -97,7 +97,12 @@ size_t build_random_string(RandomEngine &rand, char *buffer) {
if (i == size_t(location_of_decimal_separator)) { if (i == size_t(location_of_decimal_separator)) {
buffer[pos++] = '.'; buffer[pos++] = '.';
} }
buffer[pos++] = char(rand.next_digit() + '0'); buffer[pos] = char(rand.next_digit() + '0');
// We can have a leading zero only if location_of_decimal_separator = 1.
while(i == 0 && 1 != size_t(location_of_decimal_separator) && buffer[pos] == '0') {
buffer[pos] = char(rand.next_digit() + '0');
}
pos++;
} }
if (rand.next_bool()) { if (rand.next_bool()) {
if (rand.next_bool()) { if (rand.next_bool()) {
@ -174,7 +179,7 @@ bool tester(uint64_t seed, size_t volume) {
double result_value; double result_value;
auto result = auto result =
fast_float::from_chars(buffer, buffer + length, result_value); fast_float::from_chars(buffer, buffer + length, result_value);
if (result.ec != std::errc()) { if (result.ec != std::errc() && result.ec != std::errc::result_out_of_range) {
printf("parsing %.*s\n", int(length), buffer); printf("parsing %.*s\n", int(length), buffer);
std::cerr << " I could not parse " << std::endl; std::cerr << " I could not parse " << std::endl;
return false; return false;
@ -197,7 +202,7 @@ bool tester(uint64_t seed, size_t volume) {
float result_value; float result_value;
auto result = auto result =
fast_float::from_chars(buffer, buffer + length, result_value); fast_float::from_chars(buffer, buffer + length, result_value);
if (result.ec != std::errc()) { if (result.ec != std::errc() && result.ec != std::errc::result_out_of_range) {
printf("parsing %.*s\n", int(length), buffer); printf("parsing %.*s\n", int(length), buffer);
std::cerr << " I could not parse " << std::endl; std::cerr << " I could not parse " << std::endl;
return false; return false;

View File

@ -85,7 +85,7 @@ bool test() {
} }
if(begin != end) { if(begin != end) {
std::cerr << " bad ending " << std::endl; std::cerr << " bad ending " << std::endl;
return false; return false;
} }
return true; return true;
} }
@ -239,7 +239,7 @@ bool partow_test() {
T result_value; T result_value;
auto result = fast_float::from_chars(st.data(), st.data() + st.size(), auto result = fast_float::from_chars(st.data(), st.data() + st.size(),
result_value); result_value);
if (result.ec != std::errc()) { if (result.ec != std::errc() && result.ec != std::errc::result_out_of_range) {
printf("parsing %.*s\n", int(st.size()), st.data()); printf("parsing %.*s\n", int(st.size()), st.data());
std::cerr << " I could not parse " << std::endl; std::cerr << " I could not parse " << std::endl;
return false; return false;
@ -270,7 +270,7 @@ int main() {
std::cout << "32 bits checks" << std::endl; std::cout << "32 bits checks" << std::endl;
Assert(partow_test<float>()); Assert(partow_test<float>());
Assert(test<float>()); Assert(test<float>());
std::cout << "64 bits checks" << std::endl; std::cout << "64 bits checks" << std::endl;
Assert(partow_test<double>()); Assert(partow_test<double>());
Assert(test<double>()); Assert(test<double>());