diff --git a/Source/Core/Common/FloatUtils.h b/Source/Core/Common/FloatUtils.h index 959a20bb17..a841165b70 100644 --- a/Source/Core/Common/FloatUtils.h +++ b/Source/Core/Common/FloatUtils.h @@ -7,6 +7,7 @@ #include #include +#include "Common/BitUtils.h" #include "Common/CommonTypes.h" namespace Common @@ -55,54 +56,39 @@ enum : u32 FLOAT_ZERO = 0x00000000 }; -union IntDouble -{ - double d; - u64 i; - - explicit IntDouble(u64 _i) : i(_i) {} - explicit IntDouble(double _d) : d(_d) {} -}; -union IntFloat -{ - float f; - u32 i; - - explicit IntFloat(u32 _i) : i(_i) {} - explicit IntFloat(float _f) : f(_f) {} -}; - inline bool IsQNAN(double d) { - IntDouble x(d); - return ((x.i & DOUBLE_EXP) == DOUBLE_EXP) && ((x.i & DOUBLE_QBIT) == DOUBLE_QBIT); + const u64 i = BitCast(d); + return ((i & DOUBLE_EXP) == DOUBLE_EXP) && ((i & DOUBLE_QBIT) == DOUBLE_QBIT); } inline bool IsSNAN(double d) { - IntDouble x(d); - return ((x.i & DOUBLE_EXP) == DOUBLE_EXP) && ((x.i & DOUBLE_FRAC) != DOUBLE_ZERO) && - ((x.i & DOUBLE_QBIT) == DOUBLE_ZERO); + const u64 i = BitCast(d); + return ((i & DOUBLE_EXP) == DOUBLE_EXP) && ((i & DOUBLE_FRAC) != DOUBLE_ZERO) && + ((i & DOUBLE_QBIT) == DOUBLE_ZERO); } inline float FlushToZero(float f) { - IntFloat x(f); - if ((x.i & FLOAT_EXP) == 0) + u32 i = BitCast(f); + if ((i & FLOAT_EXP) == 0) { - x.i &= FLOAT_SIGN; // turn into signed zero + // Turn into signed zero + i &= FLOAT_SIGN; } - return x.f; + return BitCast(i); } inline double FlushToZero(double d) { - IntDouble x(d); - if ((x.i & DOUBLE_EXP) == 0) + u64 i = BitCast(d); + if ((i & DOUBLE_EXP) == 0) { - x.i &= DOUBLE_SIGN; // turn into signed zero + // Turn into signed zero + i &= DOUBLE_SIGN; } - return x.d; + return BitCast(i); } enum PPCFpClass diff --git a/Source/UnitTests/Common/FloatUtilsTest.cpp b/Source/UnitTests/Common/FloatUtilsTest.cpp index c1f7117162..bcc3e94cf2 100644 --- a/Source/UnitTests/Common/FloatUtilsTest.cpp +++ b/Source/UnitTests/Common/FloatUtilsTest.cpp @@ -7,6 +7,7 @@ #include +#include "Common/BitUtils.h" #include "Common/FloatUtils.h" TEST(FloatUtils, IsQNAN) @@ -51,18 +52,16 @@ TEST(FloatUtils, FlushToZero) std::uniform_int_distribution dist(0x00800000u, 0x7fffffffu); for (u32 i = 0; i <= 0x007fffffu; ++i) { - Common::IntFloat x(i); - EXPECT_EQ(+0.f, Common::FlushToZero(x.f)); + u32 i_tmp = i; + EXPECT_EQ(+0.f, Common::FlushToZero(Common::BitCast(i_tmp))); - x.i = i | 0x80000000u; - EXPECT_EQ(-0.f, Common::FlushToZero(x.f)); + i_tmp |= 0x80000000u; + EXPECT_EQ(-0.f, Common::FlushToZero(Common::BitCast(i_tmp))); - x.i = dist(engine); - Common::IntFloat y(Common::FlushToZero(x.f)); - EXPECT_EQ(x.i, y.i); + i_tmp = dist(engine); + EXPECT_EQ(i_tmp, Common::BitCast(Common::FlushToZero(Common::BitCast(i_tmp)))); - x.i |= 0x80000000u; - y.f = Common::FlushToZero(x.f); - EXPECT_EQ(x.i, y.i); + i_tmp |= 0x80000000u; + EXPECT_EQ(i_tmp, Common::BitCast(Common::FlushToZero(Common::BitCast(i_tmp)))); } } diff --git a/Source/UnitTests/VideoCommon/VertexLoaderTest.cpp b/Source/UnitTests/VideoCommon/VertexLoaderTest.cpp index 6ba3c4c464..70a8a96235 100644 --- a/Source/UnitTests/VideoCommon/VertexLoaderTest.cpp +++ b/Source/UnitTests/VideoCommon/VertexLoaderTest.cpp @@ -10,8 +10,8 @@ #include // NOLINT +#include "Common/BitUtils.h" #include "Common/Common.h" -#include "Common/FloatUtils.h" #include "VideoCommon/CPMemory.h" #include "VideoCommon/DataReader.h" #include "VideoCommon/OpcodeDecoding.h" @@ -72,14 +72,15 @@ protected: m_src.Write(val); } - void ExpectOut(float val) + void ExpectOut(float expected) { // Read unswapped. - Common::IntFloat expected(val), actual(m_dst.Read()); - if (!actual.f || actual.f != actual.f) - EXPECT_EQ(expected.i, actual.i); + const float actual = m_dst.Read(); + + if (!actual || actual != actual) + EXPECT_EQ(Common::BitCast(expected), Common::BitCast(actual)); else - EXPECT_EQ(expected.f, actual.f); + EXPECT_EQ(expected, actual); } void RunVertices(int count, int expected_count = -1)