Added float error handling

This commit is contained in:
John Wellbelove 2022-10-21 14:54:01 +01:00
parent 9aea4bf1cc
commit 5cae6659ba
2 changed files with 170 additions and 14 deletions

View File

@ -56,6 +56,7 @@ namespace etl
Not_Set,
Valid,
Invalid_Format,
Invalid_Float,
Signed_To_Unsigned,
Overflow
};
@ -64,6 +65,7 @@ namespace etl
ETL_ENUM_TYPE(Not_Set, "Not_Set")
ETL_ENUM_TYPE(Valid, "Valid")
ETL_ENUM_TYPE(Invalid_Format, "Invalid Format")
ETL_ENUM_TYPE(Invalid_Float, "Invalid Float")
ETL_ENUM_TYPE(Signed_To_Unsigned, "Signed To Unsigned")
ETL_ENUM_TYPE(Overflow, "Overflow")
ETL_END_ENUM_TYPE
@ -178,9 +180,7 @@ namespace etl
typedef char value_type;
typedef const value_type* string_type;
static ETL_CONSTANT string_type Valid_Chars = "+-.,eE0123456789abcdefABCDEF";
static ETL_CONSTANT string_type Numeric_Chars = "0123456789abcdef";
static ETL_CONSTANT string_type Floating_Point_Chars = "0123456789e.,";
static ETL_CONSTANT int Valid_Length = etl::strlen(Numeric_Chars);
static ETL_CONSTANT int Valid_Length = etl::strlen(Valid_Chars);
static ETL_CONSTANT value_type Positive_Char = '+';
static ETL_CONSTANT value_type Negative_Char = '-';
static ETL_CONSTANT value_type Radix_Point1 = '.';
@ -934,7 +934,19 @@ namespace etl
value *= pow(10.0, exponent);
result.value(value);
// Check that the result is a valid floating point number.
if (value == etl::numeric_limits<TValue>::infinity())
{
result.status(to_arithmetic_status::Overflow);
}
else if (value == etl::numeric_limits<TValue>::quiet_NaN())
{
result.status(to_arithmetic_status::Invalid_Float);
}
else
{
result.value(value);
}
}
}

View File

@ -691,6 +691,7 @@ namespace
float f2 = etl::to_arithmetic<float>(text.c_str(), text.size()).value();
CHECK_CLOSE(f1, f2, 0.00001);
CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic<float>(text.c_str(), text.size()).status());
//*********************************
text = "123.456789";
@ -699,6 +700,7 @@ namespace
f2 = etl::to_arithmetic<float>(text.c_str(), text.size()).value();
CHECK_CLOSE(f1, f2, 0.00001);
CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic<float>(text.c_str(), text.size()).status());
//*********************************
text = "-1.23456789e2";
@ -707,6 +709,7 @@ namespace
f2 = etl::to_arithmetic<float>(text.c_str(), text.size()).value();
CHECK_CLOSE(f1, f2, 0.00001);
CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic<float>(text.c_str(), text.size()).status());
//*********************************
text = "-12345.6789e-2";
@ -715,6 +718,7 @@ namespace
f2 = etl::to_arithmetic<float>(text.c_str(), text.size()).value();
CHECK_CLOSE(f1, f2, 0.00001);
CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic<float>(text.c_str(), text.size()).status());
//*********************************
text = "+12345E-2";
@ -723,6 +727,50 @@ namespace
f2 = etl::to_arithmetic<float>(text.c_str(), text.size()).value();
CHECK_CLOSE(f1, f2, 0.00001);
CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic<float>(text.c_str(), text.size()).status());
//*********************************
text = "+12345.6789E000";
f1 = strtof(text.c_str(), nullptr);
f2 = etl::to_arithmetic<float>(text.c_str(), text.size()).value();
CHECK_CLOSE(f1, f2, 0.00001);
CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic<float>(text.c_str(), text.size()).status());
}
//*************************************************************************
TEST(test_invalid_float)
{
std::string text;
//*********************************
text = " -123.456789";
CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic<float>(text.c_str(), text.size()).status());
//*********************************
text = "-123.456789 ";
CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic<float>(text.c_str(), text.size()).status());
//*********************************
text = "-12A.456789";
CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic<float>(text.c_str(), text.size()).status());
//*********************************
text = "-123.456A89";
CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic<float>(text.c_str(), text.size()).status());
//*********************************
text = "123.-456789";
CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic<float>(text.c_str(), text.size()).status());
//*********************************
text = "123E.45";
CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic<float>(text.c_str(), text.size()).status());
//*********************************
text = "123.45E1000";
CHECK_EQUAL(etl::to_arithmetic_status::Overflow, etl::to_arithmetic<float>(text.c_str(), text.size()).status());
}
//*************************************************************************
@ -733,42 +781,90 @@ namespace
//*********************************
text = "-123.45678901234567";
double f1 = strtof(text.c_str(), nullptr);
double f1 = strtod(text.c_str(), nullptr);
double f2 = etl::to_arithmetic<double>(text.c_str(), text.size()).value();
CHECK_CLOSE(f1, f2, 0.00001);
CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic<double>(text.c_str(), text.size()).status());
//*********************************
text = "123.45678901234567";
f1 = strtof(text.c_str(), nullptr);
f1 = strtod(text.c_str(), nullptr);
f2 = etl::to_arithmetic<double>(text.c_str(), text.size()).value();
CHECK_CLOSE(f1, f2, 0.00001);
CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic<double>(text.c_str(), text.size()).status());
//*********************************
text = "-1.2345678901234567e2";
f1 = strtof(text.c_str(), nullptr);
f1 = strtod(text.c_str(), nullptr);
f2 = etl::to_arithmetic<double>(text.c_str(), text.size()).value();
CHECK_CLOSE(f1, f2, 0.00001);
CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic<double>(text.c_str(), text.size()).status());
//*********************************
text = "-12345.678901234567e-2";
f1 = strtof(text.c_str(), nullptr);
f1 = strtod(text.c_str(), nullptr);
f2 = etl::to_arithmetic<double>(text.c_str(), text.size()).value();
CHECK_CLOSE(f1, f2, 0.00001);
CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic<double>(text.c_str(), text.size()).status());
//*********************************
text = "+12345E-2";
f1 = strtof(text.c_str(), nullptr);
f1 = strtod(text.c_str(), nullptr);
f2 = etl::to_arithmetic<double>(text.c_str(), text.size()).value();
CHECK_CLOSE(f1, f2, 0.00001);
CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic<double>(text.c_str(), text.size()).status());
//*********************************
text = "+12345.678901234567E0";
f1 = strtod(text.c_str(), nullptr);
f2 = etl::to_arithmetic<double>(text.c_str(), text.size()).value();
CHECK_CLOSE(f1, f2, 0.00001);
CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic<double>(text.c_str(), text.size()).status());
}
//*************************************************************************
TEST(test_invalid_double)
{
std::string text;
//*********************************
text = " -123.456789";
CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic<double>(text.c_str(), text.size()).status());
//*********************************
text = "-123.456789 ";
CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic<double>(text.c_str(), text.size()).status());
//*********************************
text = "-12A.456789";
CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic<double>(text.c_str(), text.size()).status());
//*********************************
text = "-123.456A89";
CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic<double>(text.c_str(), text.size()).status());
//*********************************
text = "123.-456789";
CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic<double>(text.c_str(), text.size()).status());
//*********************************
text = "123E.45";
CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic<double>(text.c_str(), text.size()).status());
//*********************************
text = "123.45E1000";
CHECK_EQUAL(etl::to_arithmetic_status::Overflow, etl::to_arithmetic<double>(text.c_str(), text.size()).status());
}
//*************************************************************************
@ -779,42 +875,90 @@ namespace
//*********************************
text = "-123.45678901234567";
long double f1 = strtof(text.c_str(), nullptr);
long double f1 = strtold(text.c_str(), nullptr);
long double f2 = etl::to_arithmetic<long double>(text.c_str(), text.size()).value();
CHECK_CLOSE(f1, f2, 0.00001);
CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic<double>(text.c_str(), text.size()).status());
//*********************************
text = "123.45678901234567";
f1 = strtof(text.c_str(), nullptr);
f1 = strtold(text.c_str(), nullptr);
f2 = etl::to_arithmetic<long double>(text.c_str(), text.size()).value();
CHECK_CLOSE(f1, f2, 0.00001);
CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic<double>(text.c_str(), text.size()).status());
//*********************************
text = "-1.2345678901234567e2";
f1 = strtof(text.c_str(), nullptr);
f1 = strtold(text.c_str(), nullptr);
f2 = etl::to_arithmetic<long double>(text.c_str(), text.size()).value();
CHECK_CLOSE(f1, f2, 0.00001);
CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic<double>(text.c_str(), text.size()).status());
//*********************************
text = "-12345.678901234567e-2";
f1 = strtof(text.c_str(), nullptr);
f1 = strtold(text.c_str(), nullptr);
f2 = etl::to_arithmetic<long double>(text.c_str(), text.size()).value();
CHECK_CLOSE(f1, f2, 0.00001);
CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic<double>(text.c_str(), text.size()).status());
//*********************************
text = "+12345E-2";
f1 = strtof(text.c_str(), nullptr);
f1 = strtold(text.c_str(), nullptr);
f2 = etl::to_arithmetic<long double>(text.c_str(), text.size()).value();
CHECK_CLOSE(f1, f2, 0.00001);
CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic<double>(text.c_str(), text.size()).status());
//*********************************
text = "+12345.678901234567E000";
f1 = strtold(text.c_str(), nullptr);
f2 = etl::to_arithmetic<long double>(text.c_str(), text.size()).value();
CHECK_CLOSE(f1, f2, 0.00001);
CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic<double>(text.c_str(), text.size()).status());
}
//*************************************************************************
TEST(test_invalid_long_double)
{
std::string text;
//*********************************
text = " -123.456789";
CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic<long double>(text.c_str(), text.size()).status());
//*********************************
text = "-123.456789 ";
CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic<long double>(text.c_str(), text.size()).status());
//*********************************
text = "-12A.456789";
CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic<long double>(text.c_str(), text.size()).status());
//*********************************
text = "-123.456A89";
CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic<long double>(text.c_str(), text.size()).status());
//*********************************
text = "123.-456789";
CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic<long double>(text.c_str(), text.size()).status());
//*********************************
text = "123E.45";
CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic<long double>(text.c_str(), text.size()).status());
//*********************************
text = "123.45E1000";
CHECK_EQUAL(etl::to_arithmetic_status::Overflow, etl::to_arithmetic<long double>(text.c_str(), text.size()).status());
}
//*************************************************************************