From 48712168b8222d4e48371fa1bd803d83fd90334d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lam?= Date: Thu, 28 Jan 2021 12:45:50 +0100 Subject: MathUtil: Add SaturatingCast to cast floats more safely --- Source/UnitTests/Common/MathUtilTest.cpp | 42 ++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) (limited to 'Source/UnitTests/Common/MathUtilTest.cpp') diff --git a/Source/UnitTests/Common/MathUtilTest.cpp b/Source/UnitTests/Common/MathUtilTest.cpp index c0609bbb92..e31777d16d 100644 --- a/Source/UnitTests/Common/MathUtilTest.cpp +++ b/Source/UnitTests/Common/MathUtilTest.cpp @@ -26,3 +26,45 @@ TEST(MathUtil, NextPowerOf2) EXPECT_EQ(8U, MathUtil::NextPowerOf2(6)); EXPECT_EQ(0x40000000U, MathUtil::NextPowerOf2(0x23456789)); } + +TEST(MathUtil, SaturatingCast) +{ + // Cast from an integer type to a smaller type + EXPECT_EQ(255u, (MathUtil::SaturatingCast(1000))); + EXPECT_EQ(255u, (MathUtil::SaturatingCast(1000u))); + EXPECT_EQ(255u, (MathUtil::SaturatingCast(1000))); + + // Cast from a signed integer type + EXPECT_EQ(0u, (MathUtil::SaturatingCast(-1))); + EXPECT_EQ(0u, (MathUtil::SaturatingCast(-1000))); + EXPECT_EQ(0u, (MathUtil::SaturatingCast(-1))); + EXPECT_EQ(-1000, (MathUtil::SaturatingCast(-1000))); + EXPECT_EQ(-1000, (MathUtil::SaturatingCast(-1000))); + EXPECT_EQ(-1000, (MathUtil::SaturatingCast(-1000))); + + // Cast from an unsigned integer type to a smaller integer type + EXPECT_EQ(0x7fff, (MathUtil::SaturatingCast(0xffffffffu))); + EXPECT_EQ(0x7fffffff, (MathUtil::SaturatingCast(0xffffffffu))); + + // Cast from a floating point type to an integer type + EXPECT_EQ(255u, MathUtil::SaturatingCast(1234.0)); + EXPECT_EQ(0u, MathUtil::SaturatingCast(-1234.0)); + EXPECT_EQ(127, MathUtil::SaturatingCast(5678.0)); + EXPECT_EQ(-128, MathUtil::SaturatingCast(-5678.0)); + EXPECT_EQ(65535u, MathUtil::SaturatingCast(999999.0)); + + // Negative zero + EXPECT_EQ(0u, MathUtil::SaturatingCast(0.0)); + EXPECT_EQ(0u, MathUtil::SaturatingCast(-0.0)); + EXPECT_EQ(0, MathUtil::SaturatingCast(0.0)); + EXPECT_EQ(0, MathUtil::SaturatingCast(-0.0)); + + // Edge cases + EXPECT_EQ(std::numeric_limits::max(), + MathUtil::SaturatingCast(std::numeric_limits::infinity())); + EXPECT_EQ(std::numeric_limits::min(), + MathUtil::SaturatingCast(-std::numeric_limits::infinity())); + // 16777217 = 2^24 + 1 is the first integer that cannot be represented correctly with a f32. + EXPECT_EQ(16777216, MathUtil::SaturatingCast(float(16777216))); + EXPECT_EQ(16777216, MathUtil::SaturatingCast(float(16777217))); +} -- cgit v1.2.3