mirror of
https://github.com/ciphervance/supercell-wx.git
synced 2025-10-29 22:30:04 +00:00
66 lines
1.4 KiB
C++
66 lines
1.4 KiB
C++
#include <scwx/util/float.hpp>
|
|
|
|
#include <cmath>
|
|
#include <cstring>
|
|
|
|
#ifdef _WIN32
|
|
# include <WinSock2.h>
|
|
#else
|
|
# include <arpa/inet.h>
|
|
#endif
|
|
|
|
namespace scwx
|
|
{
|
|
namespace util
|
|
{
|
|
|
|
float DecodeFloat16(std::uint16_t hex)
|
|
{
|
|
static constexpr std::uint16_t S_MASK = 0x8000;
|
|
static constexpr std::uint16_t S_LSB = 0;
|
|
static constexpr std::uint16_t S_SHIFT = 15 - S_LSB;
|
|
static constexpr std::uint16_t E_MASK = 0x7c00;
|
|
static constexpr std::uint16_t E_LSB = 5;
|
|
static constexpr std::uint16_t E_SHIFT = 15 - E_LSB;
|
|
static constexpr std::uint16_t F_MASK = 0x03ff;
|
|
static constexpr std::uint16_t F_LSB = 15;
|
|
static constexpr std::uint16_t F_SHIFT = 15 - F_LSB;
|
|
|
|
std::uint16_t sHex = (hex & S_MASK) >> S_SHIFT;
|
|
std::uint16_t eHex = (hex & E_MASK) >> E_SHIFT;
|
|
std::uint16_t fHex = (hex & F_MASK) >> F_SHIFT;
|
|
|
|
float value;
|
|
|
|
float s = std::pow(-1.0f, static_cast<float>(sHex));
|
|
float e;
|
|
float f;
|
|
|
|
if (eHex == 0)
|
|
{
|
|
e = 2.0f;
|
|
f = (fHex / std::pow(2.0f, 10.0f));
|
|
}
|
|
else
|
|
{
|
|
e = std::pow(2.0f, eHex - 16.0f);
|
|
f = (1 + fHex / std::pow(2.0f, 10.0f));
|
|
}
|
|
|
|
value = s * e * f;
|
|
|
|
return value;
|
|
}
|
|
|
|
float DecodeFloat32(std::uint16_t msw, std::uint16_t lsw)
|
|
{
|
|
std::uint32_t value = msw << 16 | lsw;
|
|
float floatValue;
|
|
|
|
std::memcpy(&floatValue, &value, sizeof(float));
|
|
|
|
return floatValue;
|
|
}
|
|
|
|
} // namespace util
|
|
} // namespace scwx
|