Vince's CSV Parser
Scientific Notation Parsing

This library has support for parsing scientific notation through csv::internals::data_type(), which is in turned called by csv::CSVField::get() when used with a floating point value type as the template parameter. Malformed scientific notation will be interpreted by this library as a regular string.

Examples

TEST_CASE("Parse Scientific Notation", "[e_notation]") {
// Test parsing e notation
long double out;
REQUIRE(data_type("1E-06", &out) == DataType::CSV_DOUBLE);
REQUIRE(is_equal(out, 0.000001L));
REQUIRE(data_type("1e-06", &out) == DataType::CSV_DOUBLE);
REQUIRE(is_equal(out, 0.000001L));
REQUIRE(data_type("2.17222E+02", &out) == DataType::CSV_DOUBLE);
REQUIRE(is_equal(out, 217.222L));
REQUIRE(data_type("4.55E+10", &out) == DataType::CSV_DOUBLE);
REQUIRE(is_equal(out, 45500000000.0L));
REQUIRE(data_type("4.55E+11", &out) == DataType::CSV_DOUBLE);
REQUIRE(is_equal(out, 455000000000.0L));
REQUIRE(data_type("4.55E-1", &out) == DataType::CSV_DOUBLE);
REQUIRE(is_equal(out, 0.455L));
REQUIRE(data_type("4.55E-5", &out) == DataType::CSV_DOUBLE);
REQUIRE(is_equal(out, 0.0000455L));
REQUIRE(data_type("4.55E-000000000005", &out) == DataType::CSV_DOUBLE);
REQUIRE(is_equal(out, 0.0000455L));
}
bool is_equal(T a, T b, T epsilon=0.001)
Definition: common.hpp:154
CONSTEXPR_14 DataType data_type(csv::string_view in, long double *const out)
Distinguishes numeric from other text values.
Definition: data_type.h:238

Supported Flavors

Many different variations of E-notation are supported, as long as there isn't a whitespace between E and the successive exponent. As seen below, the + sign is optional, and any number of zeroes is accepted.

TEST_CASE("Parse Different Flavors of Scientific Notation", "[sci_notation_diversity]") {
auto number = GENERATE(as<std::string> {},
"4.55e5", "4.55E5",
"4.55E+5", "4.55e+5",
"4.55E+05",
"4.55e0000005", "4.55E0000005",
"4.55e+0000005", "4.55E+0000005");
SECTION("Recognize 455 thousand") {
long double out;
REQUIRE(data_type(number, &out) == DataType::CSV_DOUBLE);
REQUIRE(is_equal(out, 455000.0L));
}
}