Panagiotis Christopoulos Charitos 13 gadi atpakaļ
vecāks
revīzija
8119f44af4
3 mainītis faili ar 179 papildinājumiem un 0 dzēšanām
  1. 43 0
      include/anki/math/F16.h
  2. 16 0
      include/anki/util/Array.h
  3. 120 0
      src/math/F16.cpp

+ 43 - 0
include/anki/math/F16.h

@@ -0,0 +1,43 @@
+#ifndef ANKI_MATH_F16_H
+#define ANKI_MATH_F16_H
+
+#include "anki/math/MathCommonIncludes.h"
+
+namespace anki {
+
+/// @addtogroup Math
+/// @{
+
+/// Half float
+class F16
+{
+public:
+	explicit F16();
+	explicit F16(const F32 f);
+	F16(const F16& a);
+
+	/// @name Operators with same type
+	/// @{
+	F16& operator=(const F16& b);
+	F16 operator+(const F16& b) const;
+	F16& operator+=(const F16& b);
+	F16 operator-(const F16& b) const;
+	F16& operator-=(const F16& b);
+	F16 operator*(const F16& b) const;
+	F16& operator*=(const F16& b);
+	F16 operator/(const F16& b) const;
+	F16& operator/=(const F16& b);
+	Bool operator==(const F16& b) const;
+	Bool operator!=(const F16& b) const;
+	/// @}
+
+	static F32 toF32(F16 h);
+	static F16 toF16(F32 f);
+private:
+	U16 data;
+};
+/// @}
+
+} // end namespace anki
+
+#endif

+ 16 - 0
include/anki/util/Array.h

@@ -0,0 +1,16 @@
+#ifndef ANKI_UTIL_ARRAY_H
+#define ANKI_UTIL_ARRAY_H
+
+#include <array>
+
+namespace anki {
+
+/// @addtogroup util
+/// @{
+template<typename T, size_t size>
+using Array = std::array<T, size>;
+/// @}
+
+} // end namespace anki
+
+#endif

+ 120 - 0
src/math/F16.cpp

@@ -0,0 +1,120 @@
+#include "anki/math/F16.h"
+
+namespace anki {
+
+//==============================================================================
+F16 F16::toF16(F32 f)
+{
+	F16 out;
+	I32 i = *(I32*)(&f);
+	I32 s = (i >> 16) & 0x00008000;
+	I32 e = ((i >> 23) & 0x000000ff) - (127 - 15);
+	I32 m = i & 0x007fffff;
+
+	if(e <= 0)
+	{
+		if(e < -10)
+		{
+			out.data = 0;
+		}
+		else
+		{
+			m = (m | 0x00800000) >> (1 - e);
+
+			if(m & 0x00001000) 
+			{
+				m += 0x00002000;
+			}
+
+			out.data = s | (m >> 13);
+		}
+	}
+	else if(e == 0xff - (127 - 15))
+	{
+		if(m == 0)
+		{
+			out.data = s | 0x7c00;
+		}
+		else
+		{
+			m >>= 13;
+			out.data = s | 0x7c00 | m | (m == 0);
+		}
+	}
+	else
+	{
+		if(m &  0x00001000)
+		{
+			m += 0x00002000;
+
+			if(m & 0x00800000)
+			{
+				m =  0;
+				e += 1;
+			}
+		}
+
+		if (e > 30)
+		{
+			//overflow();
+			out.data = s | 0x7c00;
+		}
+		else
+		{
+			out.data = s | (e << 10) | (m >> 13);
+		}
+	}
+
+	return out;
+}
+
+//==============================================================================
+F32 F16::toF32(F16 h)
+{
+	int s = (h.data >> 15) & 0x00000001;
+	int e = (h.data >> 10) & 0x0000001f;
+	int m = h.data & 0x000003ff;
+
+	U32 i;
+
+	if(e == 0)
+	{
+		if(m == 0)
+		{
+			i = s << 31;
+			return *(F32*)&i;
+		}
+		else
+		{
+			while(!(m & 0x00000400))
+			{
+				m <<= 1;
+				e -=  1;
+			}
+
+			e += 1;
+			m &= ~0x00000400;
+		}
+	}
+	else if(e == 31)
+	{
+		if(m == 0)
+		{
+			i = (s << 31) | 0x7f800000;
+			return *(F32*)&i;
+		}
+		else
+		{
+			i = (s << 31) | 0x7f800000 | (m << 13);
+			return *(F32*)&i;
+		}
+	}
+
+	e = e + (127 - 15);
+	m = m << 13;
+
+	i = (s << 31) | (e << 23) | m;
+	return *(F32*)&i;
+}
+
+} // end namespace anki