Przeglądaj źródła

Merge branch 'master' of github.com:bkaradzic/bx

Branimir Karadžić 9 lat temu
rodzic
commit
ed749385a3
3 zmienionych plików z 54 dodań i 18 usunięć
  1. 12 0
      include/bx/fpumath.h
  2. 36 18
      include/bx/fpumath.inl
  3. 6 0
      tests/fpumath_test.cpp

+ 12 - 0
include/bx/fpumath.h

@@ -46,6 +46,18 @@ namespace bx
 	///
 	float toDeg(float _rad);
 
+	///
+	uint32_t floatToBits(float _a);
+
+	///
+	float bitsToFloat(uint32_t _a);
+
+	///
+	uint64_t doubleToBits(double _a);
+
+	///
+	double bitsToDouble(uint64_t _a);
+
 	///
 	bool isNan(float _f);
 

+ 36 - 18
include/bx/fpumath.inl

@@ -25,46 +25,64 @@ namespace bx
 		return _rad * 180.0f / pi;
 	}
 
+	inline uint32_t floatToBits(float _a)
+	{
+		union { float f; uint32_t ui; } u = { _a };
+		return u.ui;
+	}
+
+	inline float bitsToFloat(uint32_t _a)
+	{
+		union { uint32_t ui; float f; } u = { _a };
+		return u.f;
+	}
+
+	inline uint64_t doubleToBits(double _a)
+	{
+		union { double f; uint64_t ui; } u = { _a };
+		return u.ui;
+	}
+
+	inline double bitsToDouble(uint64_t _a)
+	{
+		union { uint64_t ui; double f; } u = { _a };
+		return u.f;
+	}
+
 	inline bool isNan(float _f)
 	{
-		union { float f; uint32_t ui; } u = { _f };
-		u.ui &= INT32_MAX;
-		return u.ui > UINT32_C(0x7f800000);
+		const uint32_t tmp = floatToBits(_f) & INT32_MAX;
+		return tmp > UINT32_C(0x7f800000);
 	}
 
 	inline bool isNan(double _f)
 	{
-		union { double f; uint64_t ui; } u = { _f };
-		u.ui &= INT64_MAX;
-		return u.ui > UINT64_C(0x7ff0000000000000);
+		const uint64_t tmp = doubleToBits(_f) & INT64_MAX;
+		return tmp > UINT64_C(0x7ff0000000000000);
 	}
 
 	inline bool isFinite(float _f)
 	{
-		union { float f; uint32_t ui; } u = { _f };
-		u.ui &= INT32_MAX;
-		return u.ui < UINT32_C(0x7f800000);
+		const uint32_t tmp = floatToBits(_f) & INT32_MAX;
+		return tmp < UINT32_C(0x7f800000);
 	}
 
 	inline bool isFinite(double _f)
 	{
-		union { double f; uint64_t ui; } u = { _f };
-		u.ui &= INT64_MAX;
-		return u.ui < UINT64_C(0x7ff0000000000000);
+		const uint64_t tmp = doubleToBits(_f) & INT64_MAX;
+		return tmp < UINT64_C(0x7ff0000000000000);
 	}
 
 	inline bool isInfinite(float _f)
 	{
-		union { float f; uint32_t ui; } u = { _f };
-		u.ui &= INT32_MAX;
-		return u.ui == UINT32_C(0x7f800000);
+		const uint32_t tmp = floatToBits(_f) & INT32_MAX;
+		return tmp == UINT32_C(0x7f800000);
 	}
 
 	inline bool isInfinite(double _f)
 	{
-		union { double f; uint64_t ui; } u = { _f };
-		u.ui &= INT64_MAX;
-		return u.ui == UINT64_C(0x7ff0000000000000);
+		const uint64_t tmp = doubleToBits(_f) & INT64_MAX;
+		return tmp == UINT64_C(0x7ff0000000000000);
 	}
 
 	inline float ffloor(float _f)

+ 6 - 0
tests/fpumath_test.cpp

@@ -20,6 +20,12 @@ TEST_CASE("isFinite, isInfinite, isNan", "")
 }
 #endif // !BX_COMPILER_MSVC || BX_COMPILER_MSVC >= 1800
 
+TEST_CASE("ToBits", "")
+{
+	REQUIRE(UINT32_C(0x12345678)         == bx::floatToBits( bx::bitsToFloat( UINT32_C(0x12345678) ) ) );
+	REQUIRE(UINT64_C(0x123456789abcdef0) == bx::doubleToBits(bx::bitsToDouble(UINT32_C(0x123456789abcdef0) ) ) );
+}
+
 void mtxCheck(const float* _a, const float* _b)
 {
 	if (!bx::fequal(_a, _b, 16, 0.01f) )