69 lines
1.5 KiB
C++
69 lines
1.5 KiB
C++
#ifndef TFLOAT16_H
|
|
#define TFLOAT16_H
|
|
|
|
// crude implementation of float16 for platforms that do not support _Float16
|
|
|
|
#include <stdint.h>
|
|
|
|
class TFloat16
|
|
{
|
|
uint16_t b16;
|
|
public:
|
|
TFloat16(){ b16 = 0; }
|
|
explicit inline TFloat16(float f)
|
|
{
|
|
uint32_t i = *reinterpret_cast<uint32_t*>(&f);
|
|
uint32_t sign = (i >> 16) & 0x8000;
|
|
uint32_t exp = (i >> 23) & 0xff;
|
|
uint32_t mantisa = (i & 0x7fffff) >> 13;
|
|
|
|
b16 = 0;
|
|
if(exp < 111)
|
|
{
|
|
// do nothing it map to 0
|
|
}
|
|
else if(exp == 111)
|
|
{
|
|
b16 |= sign;
|
|
b16 |= mantisa;
|
|
}
|
|
else if(exp == 255)//inf or nan
|
|
{
|
|
b16 = 0x7c00;
|
|
b16 |= sign;
|
|
b16 |= mantisa;
|
|
}
|
|
else if(exp > 142)
|
|
{
|
|
b16 = 0x7c00;// inf
|
|
b16 |= sign;
|
|
}
|
|
else
|
|
{
|
|
b16 |= sign;
|
|
b16 |= (exp - 112) << 10;
|
|
b16 |= mantisa;
|
|
}
|
|
}
|
|
friend TFloat16 operator*(TFloat16 a, TFloat16 b)
|
|
{
|
|
return TFloat16(static_cast<float>(a) * static_cast<float>(b));
|
|
}
|
|
operator float() const
|
|
{
|
|
uint32_t i = 0;
|
|
uint32_t sign = b16 & 0x8000;
|
|
uint32_t exp = (b16 & 0x7c00) >> 10;
|
|
if(b16)
|
|
{
|
|
i |= sign << 16;
|
|
if(exp==31)i |= 0x7f800000;
|
|
else i |= (exp + 112) << 23;
|
|
i |= (b16 & 0x3ff) << 13;
|
|
}
|
|
return *reinterpret_cast<float*>(&i);
|
|
}
|
|
};
|
|
|
|
#endif // TFLOAT16_H
|