Skip to content

Commit

Permalink
iox-eclipse-iceoryx#2055 Make conversion of subnormal float fail on MSVC
Browse files Browse the repository at this point in the history
Signed-off-by: Dennis Liu <[email protected]>
  • Loading branch information
Dennis40816 committed Jan 14, 2024
1 parent ef269b7 commit 0caf7b2
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 20 deletions.
29 changes: 12 additions & 17 deletions iceoryx_hoofs/test/moduletests/test_utility_convert.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -683,37 +683,34 @@ TEST_F(convert_test, fromString_Float_EdgeCase_SubNormalFloat_ShouldFail)
{
::testing::Test::RecordProperty("TEST_ID", "68d4f096-a93c-406b-b081-fe50e4b1a2c9");

// strtof will trigger ERANGE if the input is a subnormal float, resulting in a nullopt return value.
// note that for MSVC, sub normal float is a valid input!
auto normal_float_min_eps = std::nextafter(std::numeric_limits<float>::min(), 0.0F);
std::string source = fp_to_string(std::numeric_limits<float>::min() - normal_float_min_eps);
auto float_min_dec_eps = iox::convert::from_string<float>(source.c_str());
#ifdef _WIN32
GTEST_SKIP() << "@todo iox-#2055 temporarily skipped";
#else
ASSERT_THAT(float_min_dec_eps.has_value(), Eq(false));
#endif
}

// TEST_F(convert_test, fromString_Double_EdgeCase_InRange_Success)
// {
// ::testing::Test::RecordProperty("TEST_ID", "d5e5e5ad-92ed-4229-8128-4ee82059fbf7");
TEST_F(convert_test, fromString_Double_EdgeCase_InRange_Success)
{
::testing::Test::RecordProperty("TEST_ID", "d5e5e5ad-92ed-4229-8128-4ee82059fbf7");

std::string source = fp_to_string(std::numeric_limits<double>::min());
auto double_min = iox::convert::from_string<double>(source.c_str());
ASSERT_THAT(double_min.has_value(), Eq(true));
EXPECT_THAT(double_min.value(), DoubleEq(std::numeric_limits<double>::min()));

// source = fp_to_string(std::numeric_limits<double>::lowest());
// auto double_lowest = iox::convert::from_string<double>(source.c_str());
// ASSERT_THAT(double_lowest.has_value(), Eq(true));
// EXPECT_THAT(double_lowest.value(), DoubleEq(std::numeric_limits<double>::lowest()));
source = fp_to_string(std::numeric_limits<double>::lowest());
auto double_lowest = iox::convert::from_string<double>(source.c_str());
ASSERT_THAT(double_lowest.has_value(), Eq(true));
EXPECT_THAT(double_lowest.value(), DoubleEq(std::numeric_limits<double>::lowest()));

// source = fp_to_string(std::numeric_limits<double>::max());
// auto double_max = iox::convert::from_string<double>(source.c_str());
// ASSERT_THAT(double_max.has_value(), Eq(true));
// EXPECT_THAT(double_max.value(), DoubleEq(std::numeric_limits<double>::max()));
// }
source = fp_to_string(std::numeric_limits<double>::max());
auto double_max = iox::convert::from_string<double>(source.c_str());
ASSERT_THAT(double_max.has_value(), Eq(true));
EXPECT_THAT(double_max.value(), DoubleEq(std::numeric_limits<double>::max()));
}

TEST_F(convert_test, fromString_Double_EdgeCase_SubNormalDouble_ShouldFailExcept)
{
Expand All @@ -726,7 +723,6 @@ TEST_F(convert_test, fromString_Double_EdgeCase_SubNormalDouble_ShouldFailExcept
GTEST_SKIP() << "@todo iox-#2055 temporarily skipped";
#else
ASSERT_THAT(double_min_dec_eps.has_value(), Eq(false));
#endif
}

TEST_F(convert_test, fromString_LongDouble_EdgeCase_InRange_Success)
Expand Down Expand Up @@ -761,7 +757,6 @@ TEST_F(convert_test, fromString_LongDouble_EdgeCase_SubNormalLongDouble_ShouldFa
GTEST_SKIP() << "@todo iox-#2055 temporarily skipped";
#else
ASSERT_THAT(long_double_min_dec_eps.has_value(), Eq(false));
#endif
}

/// NORMAL FLOATING POINT TYPE EDGE CASES END
Expand Down
9 changes: 6 additions & 3 deletions iceoryx_hoofs/utility/include/iox/detail/convert.inl
Original file line number Diff line number Diff line change
Expand Up @@ -363,16 +363,20 @@ inline bool convert::is_within_range(const SourceType& source_val) noexcept
{
return true;
}
// is_arithmetic_v
if constexpr (std::is_floating_point_v<SourceType>)
{
// special cases for floating point
if (std::isnan(source_val) || std::isinf(source_val))
{
return true;
}
#ifdef _MSC_VER
if (!std::isnormal(source_val) && (source_val != 0.0))
{
return false;
}
#endif
}

// out of range (upper bound)
if (source_val > std::numeric_limits<TargetType>::max())
{
Expand All @@ -381,7 +385,6 @@ inline bool convert::is_within_range(const SourceType& source_val) noexcept
<< std::numeric_limits<TargetType>::max());
return false;
}

// out of range (lower bound)
if (source_val < std::numeric_limits<TargetType>::lowest())
{
Expand Down

0 comments on commit 0caf7b2

Please sign in to comment.