accept denormal floating point numbers in tokenizer class and utils::numeric()

This commit is contained in:
Axel Kohlmeyer
2025-06-04 21:07:18 -04:00
parent b3f160c118
commit f5b64118cc
2 changed files with 16 additions and 1 deletions

View File

@ -19,6 +19,8 @@
#include "fmt/format.h"
#include "utils.h"
#include <cmath>
#include <cstdlib>
#include <utility>
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);

View File

@ -34,6 +34,8 @@
#include <cctype>
#include <cerrno>
#include <cmath>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <stdexcept>
@ -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);