Minor fix.

This commit is contained in:
Daniel Lemire 2020-10-29 16:40:20 -04:00
parent 0b8ba8f978
commit f7d3cdc426
12 changed files with 62 additions and 14 deletions

View File

@ -189,10 +189,11 @@ decimal parse_decimal(const char *p, const char *pend) noexcept {
} }
while ((p != pend) && is_integer(*p)) { while ((p != pend) && is_integer(*p)) {
if (answer.num_digits + 1 < max_digits) { 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 { } else {
answer.truncated = true; answer.truncated = true;
} }
answer.num_digits++;
++p; ++p;
} }
const char *first_after_period{}; const char *first_after_period{};
@ -229,7 +230,6 @@ decimal parse_decimal(const char *p, const char *pend) noexcept {
} }
answer.decimal_point = int32_t(first_after_period - p); answer.decimal_point = int32_t(first_after_period - p);
} }
if ((p != pend) && (('e' == *p) || ('E' == *p))) { if ((p != pend) && (('e' == *p) || ('E' == *p))) {
++p; ++p;
bool neg_exp = false; bool neg_exp = false;

View File

@ -68,7 +68,7 @@ template <typename binary>
fastfloat_really_inline fastfloat_really_inline
adjusted_mantissa compute_float(int64_t q, uint64_t w) noexcept { adjusted_mantissa compute_float(int64_t q, uint64_t w) noexcept {
adjusted_mantissa answer; adjusted_mantissa answer;
if ((w == 0) || (q < smallest_power_of_five) ){ if ((w == 0) || (q < smallest_power_of_five)) {
answer.power2 = 0; answer.power2 = 0;
answer.mantissa = 0; answer.mantissa = 0;
// result should be zero // result should be zero

View File

@ -354,6 +354,7 @@ adjusted_mantissa compute_float(decimal &d) {
template <typename binary> template <typename binary>
adjusted_mantissa parse_long_mantissa(const char *first, const char* last) { adjusted_mantissa parse_long_mantissa(const char *first, const char* last) {
decimal d = parse_decimal(first, last); decimal d = parse_decimal(first, last);
std::cout << " decimall " << d << std::endl;
// In some cases we can get lucky and looking at only the first 19 digits is enough. // In some cases we can get lucky and looking at only the first 19 digits is enough.
// Let us try that. // Let us try that.
const uint64_t mantissa = d.to_truncated_mantissa(); const uint64_t mantissa = d.to_truncated_mantissa();

View File

@ -46,7 +46,14 @@ bool basic_test_32bit(std::string vals, float val) {
std::cerr << " I could not parse " << vals << std::endl; std::cerr << " I could not parse " << vals << std::endl;
return false; return false;
} }
if (std::isnan(val)) { std::cout << copysign(1,result_value) << std::endl;
std::cout << copysign(1,val) << std::endl;
if(copysign(1,result_value) != copysign(1,val)) {
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << val
<< std::endl;
return false;
} else if (std::isnan(val)) {
if (!std::isnan(result_value)) { if (!std::isnan(result_value)) {
std::cerr << "not nan" << result_value << std::endl; std::cerr << "not nan" << result_value << std::endl;
return false; return false;
@ -83,7 +90,11 @@ bool basic_test_64bit(std::string vals, double val) {
std::cerr << " I could not parse " << vals << std::endl; std::cerr << " I could not parse " << vals << std::endl;
return false; return false;
} }
if (std::isnan(val)) { if(copysign(1,result_value) != copysign(1,val)) {
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << val
<< std::endl;
return false;
} else if (std::isnan(val)) {
if (!std::isnan(result_value)) { if (!std::isnan(result_value)) {
std::cerr << "not nan" << result_value << std::endl; std::cerr << "not nan" << result_value << std::endl;
return false; return false;
@ -139,6 +150,7 @@ int main() {
std::cout << "======= 64 bits " << std::endl; std::cout << "======= 64 bits " << std::endl;
Assert(basic_test_64bit("-0",-0.0));
Assert(basic_test_64bit("2.22507385850720212418870147920222032907240528279439037814303133837435107319244194686754406432563881851382188218502438069999947733013005649884107791928741341929297200970481951993067993290969042784064731682041565926728632933630474670123316852983422152744517260835859654566319282835244787787799894310779783833699159288594555213714181128458251145584319223079897504395086859412457230891738946169368372321191373658977977723286698840356390251044443035457396733706583981055420456693824658413747607155981176573877626747665912387199931904006317334709003012790188175203447190250028061277777916798391090578584006464715943810511489154282775041174682194133952466682503431306181587829379004205392375072083366693241580002758391118854188641513168478436313080237596295773983001708984375e-308", 0x1.0000000000002p-1022)); Assert(basic_test_64bit("2.22507385850720212418870147920222032907240528279439037814303133837435107319244194686754406432563881851382188218502438069999947733013005649884107791928741341929297200970481951993067993290969042784064731682041565926728632933630474670123316852983422152744517260835859654566319282835244787787799894310779783833699159288594555213714181128458251145584319223079897504395086859412457230891738946169368372321191373658977977723286698840356390251044443035457396733706583981055420456693824658413747607155981176573877626747665912387199931904006317334709003012790188175203447190250028061277777916798391090578584006464715943810511489154282775041174682194133952466682503431306181587829379004205392375072083366693241580002758391118854188641513168478436313080237596295773983001708984375e-308", 0x1.0000000000002p-1022));
Assert(basic_test_64bit("1.0000000000000006661338147750939242541790008544921875",1.0000000000000007)); Assert(basic_test_64bit("1.0000000000000006661338147750939242541790008544921875",1.0000000000000007));
Assert(basic_test_64bit("1090544144181609348835077142190",0x1.b8779f2474dfbp+99)); Assert(basic_test_64bit("1090544144181609348835077142190",0x1.b8779f2474dfbp+99));
@ -191,9 +203,12 @@ int main() {
Assert(basic_test_64bit("45035996.273704985", 45035996.273704985)); Assert(basic_test_64bit("45035996.273704985", 45035996.273704985));
Assert(basic_test_64bit("0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044501477170144022721148195934182639518696390927032912960468522194496444440421538910330590478162701758282983178260792422137401728773891892910553144148156412434867599762821265346585071045737627442980259622449029037796981144446145705102663115100318287949527959668236039986479250965780342141637013812613333119898765515451440315261253813266652951306000184917766328660755595837392240989947807556594098101021612198814605258742579179000071675999344145086087205681577915435923018910334964869420614052182892431445797605163650903606514140377217442262561590244668525767372446430075513332450079650686719491377688478005309963967709758965844137894433796621993967316936280457084866613206797017728916080020698679408551343728867675409720757232455434770912461317493580281734466552734375", 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044501477170144022721148195934182639518696390927032912960468522194496444440421538910330590478162701758282983178260792422137401728773891892910553144148156412434867599762821265346585071045737627442980259622449029037796981144446145705102663115100318287949527959668236039986479250965780342141637013812613333119898765515451440315261253813266652951306000184917766328660755595837392240989947807556594098101021612198814605258742579179000071675999344145086087205681577915435923018910334964869420614052182892431445797605163650903606514140377217442262561590244668525767372446430075513332450079650686719491377688478005309963967709758965844137894433796621993967316936280457084866613206797017728916080020698679408551343728867675409720757232455434770912461317493580281734466552734375)); Assert(basic_test_64bit("0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044501477170144022721148195934182639518696390927032912960468522194496444440421538910330590478162701758282983178260792422137401728773891892910553144148156412434867599762821265346585071045737627442980259622449029037796981144446145705102663115100318287949527959668236039986479250965780342141637013812613333119898765515451440315261253813266652951306000184917766328660755595837392240989947807556594098101021612198814605258742579179000071675999344145086087205681577915435923018910334964869420614052182892431445797605163650903606514140377217442262561590244668525767372446430075513332450079650686719491377688478005309963967709758965844137894433796621993967316936280457084866613206797017728916080020698679408551343728867675409720757232455434770912461317493580281734466552734375", 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000044501477170144022721148195934182639518696390927032912960468522194496444440421538910330590478162701758282983178260792422137401728773891892910553144148156412434867599762821265346585071045737627442980259622449029037796981144446145705102663115100318287949527959668236039986479250965780342141637013812613333119898765515451440315261253813266652951306000184917766328660755595837392240989947807556594098101021612198814605258742579179000071675999344145086087205681577915435923018910334964869420614052182892431445797605163650903606514140377217442262561590244668525767372446430075513332450079650686719491377688478005309963967709758965844137894433796621993967316936280457084866613206797017728916080020698679408551343728867675409720757232455434770912461317493580281734466552734375));
Assert(basic_test_64bit("0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022250738585072008890245868760858598876504231122409594654935248025624400092282356951787758888037591552642309780950434312085877387158357291821993020294379224223559819827501242041788969571311791082261043971979604000454897391938079198936081525613113376149842043271751033627391549782731594143828136275113838604094249464942286316695429105080201815926642134996606517803095075913058719846423906068637102005108723282784678843631944515866135041223479014792369585208321597621066375401613736583044193603714778355306682834535634005074073040135602968046375918583163124224521599262546494300836851861719422417646455137135420132217031370496583210154654068035397417906022589503023501937519773030945763173210852507299305089761582519159720757232455434770912461317493580281734466552734375", 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022250738585072008890245868760858598876504231122409594654935248025624400092282356951787758888037591552642309780950434312085877387158357291821993020294379224223559819827501242041788969571311791082261043971979604000454897391938079198936081525613113376149842043271751033627391549782731594143828136275113838604094249464942286316695429105080201815926642134996606517803095075913058719846423906068637102005108723282784678843631944515866135041223479014792369585208321597621066375401613736583044193603714778355306682834535634005074073040135602968046375918583163124224521599262546494300836851861719422417646455137135420132217031370496583210154654068035397417906022589503023501937519773030945763173210852507299305089761582519159720757232455434770912461317493580281734466552734375)); Assert(basic_test_64bit("0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022250738585072008890245868760858598876504231122409594654935248025624400092282356951787758888037591552642309780950434312085877387158357291821993020294379224223559819827501242041788969571311791082261043971979604000454897391938079198936081525613113376149842043271751033627391549782731594143828136275113838604094249464942286316695429105080201815926642134996606517803095075913058719846423906068637102005108723282784678843631944515866135041223479014792369585208321597621066375401613736583044193603714778355306682834535634005074073040135602968046375918583163124224521599262546494300836851861719422417646455137135420132217031370496583210154654068035397417906022589503023501937519773030945763173210852507299305089761582519159720757232455434770912461317493580281734466552734375", 0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000022250738585072008890245868760858598876504231122409594654935248025624400092282356951787758888037591552642309780950434312085877387158357291821993020294379224223559819827501242041788969571311791082261043971979604000454897391938079198936081525613113376149842043271751033627391549782731594143828136275113838604094249464942286316695429105080201815926642134996606517803095075913058719846423906068637102005108723282784678843631944515866135041223479014792369585208321597621066375401613736583044193603714778355306682834535634005074073040135602968046375918583163124224521599262546494300836851861719422417646455137135420132217031370496583210154654068035397417906022589503023501937519773030945763173210852507299305089761582519159720757232455434770912461317493580281734466552734375));
Assert(basic_test_64bit("1438456663141390273526118207642235581183227845246331231162636653790368152091394196930365828634687637948157940776599182791387527135353034738357134110310609455693900824193549772792016543182680519740580354365467985440183598701312257624545562331397018329928613196125590274187720073914818062530830316533158098624984118889298281371812288789537310599037529113415438738954894752124724983067241108764488346454376699018673078404751121414804937224240805993123816932326223683090770561597570457793932985826162604255884529134126396282202126526253389383421806727954588525596114379801269094096329805054803089299736996870951258573010877404407451953846698609198213926882692078557033228265259305481198526059813164469187586693257335779522020407645498684263339921905227556616698129967412891282231685504660671277927198290009824680186319750978665734576683784255802269708917361719466043175201158849097881370477111850171579869056016061666173029059588433776015644439705050377554277696143928278093453792803846252715966016733222646442382892123940052441346822429721593884378212558701004356924243030059517489346646577724622498919752597382095222500311124181823512251071356181769376577651390028297796156208815375089159128394945710515861334486267101797497111125909272505194792870889617179758703442608016143343262159998149700606597792535574457560429226974273443630323818747730771316763398572110874959981923732463076884528677392654150010269822239401993427482376513231389212353583573566376915572650916866553612366187378959554983566712767093372906030188976220169058025354973622211666504549316958271880975697143546564469806791358707318873075708383345004090151974068325838177531266954177406661392229801349994695941509935655355652985723782153570084089560139142231.738475042362596875449154552392299548947138162081694168675340677843807613129780449323363759027012972466987370921816813162658754726545121090545507240267000456594786540949605260722461937870630634874991729398208026467698131898691830012167897399682179601734569071423681e-733", std::numeric_limits<double>::infinity()));
std::cout << std::endl; std::cout << std::endl;
std::cout << "======= 32 bits " << std::endl; std::cout << "======= 32 bits " << std::endl;
Assert(basic_test_32bit("-0",-0.0f));
Assert(basic_test_32bit("1090544144181609348835077142190",0x1.b877ap+99f)); Assert(basic_test_32bit("1090544144181609348835077142190",0x1.b877ap+99f));
Assert(basic_test_32bit("1.1754943508e-38",1.1754943508e-38f)); Assert(basic_test_32bit("1.1754943508e-38",1.1754943508e-38f));
Assert(basic_test_32bit("30219.0830078125",30219.0830078125f)); Assert(basic_test_32bit("30219.0830078125",30219.0830078125f));

View File

@ -30,7 +30,11 @@ void allvalues() {
std::cerr << "parsing error ? " << buffer << std::endl; std::cerr << "parsing error ? " << buffer << std::endl;
abort(); abort();
} }
if (std::isnan(v)) { if(copysign(1,result_value) != copysign(1,v)) {
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v
<< std::endl;
abort();
} else if (std::isnan(v)) {
if (!std::isnan(result_value)) { if (!std::isnan(result_value)) {
std::cerr << "not nan" << buffer << std::endl; std::cerr << "not nan" << buffer << std::endl;
abort(); abort();

View File

@ -31,7 +31,11 @@ void all_32bit_values() {
std::cerr << "parsing error ? " << buffer << std::endl; std::cerr << "parsing error ? " << buffer << std::endl;
abort(); abort();
} }
if (std::isnan(v)) { if(copysign(1,result_value) != copysign(1,v)) {
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v
<< std::endl;
abort();
} else if (std::isnan(v)) {
if (!std::isnan(result_value)) { if (!std::isnan(result_value)) {
std::cerr << "not nan" << buffer << std::endl; std::cerr << "not nan" << buffer << std::endl;
abort(); abort();

View File

@ -75,7 +75,11 @@ void allvalues() {
std::cerr << "parsing error ? " << buffer << std::endl; std::cerr << "parsing error ? " << buffer << std::endl;
abort(); abort();
} }
if (std::isnan(v)) { if(copysign(1,result_value) != copysign(1,v)) {
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v
<< std::endl;
abort();
} else if (std::isnan(v)) {
if (!std::isnan(result_value)) { if (!std::isnan(result_value)) {
std::cerr << "not nan" << buffer << std::endl; std::cerr << "not nan" << buffer << std::endl;
abort(); abort();

View File

@ -30,7 +30,11 @@ void allvalues() {
std::cerr << "parsing error ? " << buffer << std::endl; std::cerr << "parsing error ? " << buffer << std::endl;
abort(); abort();
} }
if (std::isnan(v)) { if(copysign(1,result_value) != copysign(1,v)) {
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v
<< std::endl;
abort();
} else if (std::isnan(v)) {
if (!std::isnan(result_value)) { if (!std::isnan(result_value)) {
std::cerr << "not nan" << buffer << std::endl; std::cerr << "not nan" << buffer << std::endl;
abort(); abort();

View File

@ -30,7 +30,11 @@ void all_32bit_values() {
std::cerr << "parsing error ? " << buffer << std::endl; std::cerr << "parsing error ? " << buffer << std::endl;
abort(); abort();
} }
if (std::isnan(v)) { if(copysign(1,result_value) != copysign(1,v)) {
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v
<< std::endl;
abort();
} else if (std::isnan(v)) {
if (!std::isnan(result_value)) { if (!std::isnan(result_value)) {
std::cerr << "not nan" << buffer << std::endl; std::cerr << "not nan" << buffer << std::endl;
abort(); abort();

View File

@ -60,7 +60,11 @@ void random_values(size_t N) {
abort(); abort();
} }
} }
if (std::isnan(v)) { if(copysign(1,result_value) != copysign(1,v)) {
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v
<< std::endl;
abort();
} else if (std::isnan(v)) {
if (!std::isnan(result_value)) { if (!std::isnan(result_value)) {
std::cerr << "not nan" << buffer << std::endl; std::cerr << "not nan" << buffer << std::endl;
errors++; errors++;

View File

@ -62,7 +62,11 @@ void random_values(size_t N) {
abort(); abort();
} }
} }
if (std::isnan(v)) { if(copysign(1,result_value) != copysign(1,v)) {
std::cerr << "I got " << std::hexfloat << result_value << " but I was expecting " << v
<< std::endl;
abort();
} else if (std::isnan(v)) {
if (!std::isnan(result_value)) { if (!std::isnan(result_value)) {
std::cerr << "not nan" << buffer << std::endl; std::cerr << "not nan" << buffer << std::endl;
errors++; errors++;

View File

@ -41,7 +41,7 @@ public:
char next_char() { return static_cast<char>(next()); } char next_char() { return static_cast<char>(next()); }
double next_double() { return static_cast<double>(next()); } double next_double() { return static_cast<double>(next()); }
int next_ranged_int(int min, int max) { // min and max are include int next_ranged_int(int min, int max) { // min and max are included
// Adapted from // Adapted from
// https://lemire.me/blog/2019/06/06/nearly-divisionless-random-integer-generation-on-various-systems/ // https://lemire.me/blog/2019/06/06/nearly-divisionless-random-integer-generation-on-various-systems/
/* if (min == max) { /* if (min == max) {
@ -73,6 +73,10 @@ size_t build_random_string(RandomEngine &rand, char *buffer) {
buffer[pos++] = '-'; buffer[pos++] = '-';
} }
int number_of_digits = rand.next_ranged_int(1, 100); int number_of_digits = rand.next_ranged_int(1, 100);
if(number_of_digits == 100) {
// With low probability, we want to allow very long strings just to stress the system.
number_of_digits = rand.next_ranged_int(1, 2000);
}
int location_of_decimal_separator = rand.next_ranged_int(1, number_of_digits); int location_of_decimal_separator = rand.next_ranged_int(1, number_of_digits);
for (size_t i = 0; i < number_of_digits; i++) { for (size_t i = 0; i < number_of_digits; i++) {
if (i == location_of_decimal_separator) { if (i == location_of_decimal_separator) {
@ -143,7 +147,7 @@ std::pair<float, bool> strtof_from_string(char *st) {
* and we verify that we get the same answer with with fast_float::from_chars. * and we verify that we get the same answer with with fast_float::from_chars.
*/ */
bool tester(int seed, size_t volume) { bool tester(int seed, size_t volume) {
char buffer[1024]; // large buffer (can't overflow) char buffer[4096]; // large buffer (can't overflow)
RandomEngine rand(seed); RandomEngine rand(seed);
for (size_t i = 0; i < volume; i++) { for (size_t i = 0; i < volume; i++) {
if((i%100000) == 0) { std::cout << "."; std::cout.flush(); } if((i%100000) == 0) { std::cout << "."; std::cout.flush(); }