diff --git a/src/tokenizer.cpp b/src/tokenizer.cpp index a2b95ab89e..22f5f04a9b 100644 --- a/src/tokenizer.cpp +++ b/src/tokenizer.cpp @@ -19,6 +19,8 @@ #include "fmt/format.h" #include "utils.h" +#include +#include #include using namespace LAMMPS_NS; @@ -365,6 +367,11 @@ double ValueTokenizer::next_double() return val; // rethrow exceptions from std::stod() } catch (std::out_of_range const &) { + // could be a denormal number. try again with std::strtod(). + char *end; + auto val = std::strtod(current.c_str(), &end); + // return value of denormal + if ((val != 0.0) && (val > -HUGE_VAL) && (val < HUGE_VAL)) return val; throw InvalidFloatException(current); } catch (std::invalid_argument const &) { throw InvalidFloatException(current); diff --git a/src/utils.cpp b/src/utils.cpp index 31fcb5867e..c5f4819b88 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -34,6 +34,8 @@ #include #include +#include +#include #include #include #include @@ -529,7 +531,7 @@ double utils::numeric(const char *file, int line, const std::string &str, bool d lmp->error->all(file, line, msg); } - double rv = 0; + double rv = 0.0; auto msg = fmt::format("Floating point number {} in input script or data file is invalid", buf); try { std::size_t endpos; @@ -546,6 +548,12 @@ double utils::numeric(const char *file, int line, const std::string &str, bool d else lmp->error->all(file, line, msg); } catch (std::out_of_range const &) { + // could be a denormal number. try again with std::strtod(). + char *end; + rv = std::strtod(buf.c_str(), &end); + // return value if denormal + if ((rv != 0.0) && (rv > -HUGE_VAL) && (rv < HUGE_VAL)) return rv; + msg = fmt::format("Floating point number {} in input script or data file is out of range", buf); if (do_abort) lmp->error->one(file, line, msg);