diff --git a/include/etl/to_arithmetic.h b/include/etl/to_arithmetic.h index 6b6b44b5..b13dbffa 100644 --- a/include/etl/to_arithmetic.h +++ b/include/etl/to_arithmetic.h @@ -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::infinity()) + { + result.status(to_arithmetic_status::Overflow); + } + else if (value == etl::numeric_limits::quiet_NaN()) + { + result.status(to_arithmetic_status::Invalid_Float); + } + else + { + result.value(value); + } } } diff --git a/test/test_string_to_arithmetic.cpp b/test/test_string_to_arithmetic.cpp index 73cef6d1..74765190 100644 --- a/test/test_string_to_arithmetic.cpp +++ b/test/test_string_to_arithmetic.cpp @@ -691,6 +691,7 @@ namespace float f2 = etl::to_arithmetic(text.c_str(), text.size()).value(); CHECK_CLOSE(f1, f2, 0.00001); + CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic(text.c_str(), text.size()).status()); //********************************* text = "123.456789"; @@ -699,6 +700,7 @@ namespace f2 = etl::to_arithmetic(text.c_str(), text.size()).value(); CHECK_CLOSE(f1, f2, 0.00001); + CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic(text.c_str(), text.size()).status()); //********************************* text = "-1.23456789e2"; @@ -707,6 +709,7 @@ namespace f2 = etl::to_arithmetic(text.c_str(), text.size()).value(); CHECK_CLOSE(f1, f2, 0.00001); + CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic(text.c_str(), text.size()).status()); //********************************* text = "-12345.6789e-2"; @@ -715,6 +718,7 @@ namespace f2 = etl::to_arithmetic(text.c_str(), text.size()).value(); CHECK_CLOSE(f1, f2, 0.00001); + CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic(text.c_str(), text.size()).status()); //********************************* text = "+12345E-2"; @@ -723,6 +727,50 @@ namespace f2 = etl::to_arithmetic(text.c_str(), text.size()).value(); CHECK_CLOSE(f1, f2, 0.00001); + CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic(text.c_str(), text.size()).status()); + + //********************************* + text = "+12345.6789E000"; + + f1 = strtof(text.c_str(), nullptr); + f2 = etl::to_arithmetic(text.c_str(), text.size()).value(); + + CHECK_CLOSE(f1, f2, 0.00001); + CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic(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(text.c_str(), text.size()).status()); + + //********************************* + text = "-123.456789 "; + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).status()); + + //********************************* + text = "-12A.456789"; + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).status()); + + //********************************* + text = "-123.456A89"; + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).status()); + + //********************************* + text = "123.-456789"; + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).status()); + + //********************************* + text = "123E.45"; + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).status()); + + //********************************* + text = "123.45E1000"; + CHECK_EQUAL(etl::to_arithmetic_status::Overflow, etl::to_arithmetic(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(text.c_str(), text.size()).value(); CHECK_CLOSE(f1, f2, 0.00001); + CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic(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(text.c_str(), text.size()).value(); CHECK_CLOSE(f1, f2, 0.00001); + CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic(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(text.c_str(), text.size()).value(); CHECK_CLOSE(f1, f2, 0.00001); + CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic(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(text.c_str(), text.size()).value(); CHECK_CLOSE(f1, f2, 0.00001); + CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic(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(text.c_str(), text.size()).value(); CHECK_CLOSE(f1, f2, 0.00001); + CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic(text.c_str(), text.size()).status()); + + //********************************* + text = "+12345.678901234567E0"; + + f1 = strtod(text.c_str(), nullptr); + f2 = etl::to_arithmetic(text.c_str(), text.size()).value(); + + CHECK_CLOSE(f1, f2, 0.00001); + CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic(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(text.c_str(), text.size()).status()); + + //********************************* + text = "-123.456789 "; + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).status()); + + //********************************* + text = "-12A.456789"; + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).status()); + + //********************************* + text = "-123.456A89"; + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).status()); + + //********************************* + text = "123.-456789"; + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).status()); + + //********************************* + text = "123E.45"; + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).status()); + + //********************************* + text = "123.45E1000"; + CHECK_EQUAL(etl::to_arithmetic_status::Overflow, etl::to_arithmetic(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(text.c_str(), text.size()).value(); CHECK_CLOSE(f1, f2, 0.00001); + CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic(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(text.c_str(), text.size()).value(); CHECK_CLOSE(f1, f2, 0.00001); + CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic(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(text.c_str(), text.size()).value(); CHECK_CLOSE(f1, f2, 0.00001); + CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic(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(text.c_str(), text.size()).value(); CHECK_CLOSE(f1, f2, 0.00001); + CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic(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(text.c_str(), text.size()).value(); CHECK_CLOSE(f1, f2, 0.00001); + CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic(text.c_str(), text.size()).status()); + + //********************************* + text = "+12345.678901234567E000"; + + f1 = strtold(text.c_str(), nullptr); + f2 = etl::to_arithmetic(text.c_str(), text.size()).value(); + + CHECK_CLOSE(f1, f2, 0.00001); + CHECK_EQUAL(etl::to_arithmetic_status::Valid, etl::to_arithmetic(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(text.c_str(), text.size()).status()); + + //********************************* + text = "-123.456789 "; + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).status()); + + //********************************* + text = "-12A.456789"; + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).status()); + + //********************************* + text = "-123.456A89"; + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).status()); + + //********************************* + text = "123.-456789"; + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).status()); + + //********************************* + text = "123E.45"; + CHECK_EQUAL(etl::to_arithmetic_status::Invalid_Format, etl::to_arithmetic(text.c_str(), text.size()).status()); + + //********************************* + text = "123.45E1000"; + CHECK_EQUAL(etl::to_arithmetic_status::Overflow, etl::to_arithmetic(text.c_str(), text.size()).status()); } //*************************************************************************