diff options
| author | Tillmann Karras <tilkax@gmail.com> | 2014-03-24 03:11:11 +0100 |
|---|---|---|
| committer | Tillmann Karras <tilkax@gmail.com> | 2014-03-24 16:14:22 +0100 |
| commit | e0baed850fcf75c6920e41f627fb06048a85985a (patch) | |
| tree | 0ee7d29cd576e576218317eec026f7c03b379bfd /Source/UnitTests/Common/MathUtilTest.cpp | |
| parent | af525266d4d0667fe1a6be589e0a83131a829783 (diff) | |
MathUtilTest: add test for FlushToZero
Diffstat (limited to 'Source/UnitTests/Common/MathUtilTest.cpp')
| -rw-r--r-- | Source/UnitTests/Common/MathUtilTest.cpp | 43 |
1 files changed, 42 insertions, 1 deletions
diff --git a/Source/UnitTests/Common/MathUtilTest.cpp b/Source/UnitTests/Common/MathUtilTest.cpp index 56ade34522..d2056df3f9 100644 --- a/Source/UnitTests/Common/MathUtilTest.cpp +++ b/Source/UnitTests/Common/MathUtilTest.cpp @@ -4,6 +4,7 @@ #include <gtest/gtest.h> #include <limits> +#include <random> #include "Common/MathUtil.h" @@ -29,7 +30,7 @@ TEST(MathUtil, Clamp) TEST(MathUtil, IsINF) { - EXPECT_TRUE(MathUtil::IsINF( std::numeric_limits<double>::infinity())); + EXPECT_TRUE(MathUtil::IsINF(+std::numeric_limits<double>::infinity())); EXPECT_TRUE(MathUtil::IsINF(-std::numeric_limits<double>::infinity())); } @@ -63,3 +64,43 @@ TEST(MathUtil, Log2) EXPECT_EQ(3, Log2(15)); EXPECT_EQ(63, Log2(0xFFFFFFFFFFFFFFFFull)); } + +TEST(MathUtil, FlushToZero) +{ + // To test the software implementation we need to make sure FTZ and DAZ are disabled. + // Using volatile here to ensure the compiler doesn't constant-fold it, + // we want the multiplication to occur at test runtime. + volatile float s = std::numeric_limits<float>::denorm_min(); + volatile double d = std::numeric_limits<double>::denorm_min(); + EXPECT_LT(0, s * 2); + EXPECT_LT(0, d * 2); + + EXPECT_EQ(+0, MathUtil::FlushToZero(+std::numeric_limits<double>::denorm_min())); + EXPECT_EQ(-0, MathUtil::FlushToZero(-std::numeric_limits<double>::denorm_min())); + EXPECT_EQ(+0, MathUtil::FlushToZero(+std::numeric_limits<double>::min() / 2)); + EXPECT_EQ(-0, MathUtil::FlushToZero(-std::numeric_limits<double>::min() / 2)); + EXPECT_EQ(std::numeric_limits<double>::min(), MathUtil::FlushToZero(std::numeric_limits<double>::min())); + EXPECT_EQ(std::numeric_limits<double>::max(), MathUtil::FlushToZero(std::numeric_limits<double>::max())); + EXPECT_EQ(+std::numeric_limits<double>::infinity(), MathUtil::FlushToZero(+std::numeric_limits<double>::infinity())); + EXPECT_EQ(-std::numeric_limits<double>::infinity(), MathUtil::FlushToZero(-std::numeric_limits<double>::infinity())); + + // Test all subnormals as well as an equally large set of random normal floats. + std::default_random_engine engine(0); + std::uniform_int_distribution<u32> dist(0x00800000u, 0x7fffffffu); + for (u32 i = 0; i <= 0x007fffffu; ++i) + { + MathUtil::IntFloat x(i); + EXPECT_EQ(+0, MathUtil::FlushToZero(x.f)); + + x.i = i | 0x80000000u; + EXPECT_EQ(-0, MathUtil::FlushToZero(x.f)); + + x.i = dist(engine); + MathUtil::IntFloat y(MathUtil::FlushToZero(x.f)); + EXPECT_EQ(x.i, y.i); + + x.i |= 0x80000000u; + y.f = MathUtil::FlushToZero(x.f); + EXPECT_EQ(x.i, y.i); + } +} |
