Skip to content

Instantly share code, notes, and snippets.

@enp1s0
Created December 4, 2019 04:42
Show Gist options
  • Save enp1s0/66524ada6ab596eed8f88aee419efa0c to your computer and use it in GitHub Desktop.
Save enp1s0/66524ada6ab596eed8f88aee419efa0c to your computer and use it in GitHub Desktop.
is_nan
// https://en.wikipedia.org/wiki/Half-precision_floating-point_format
#include <cmath>
#include <iostream>
using half = std::uint16_t;
bool is_nan(const half a) {
return (((a >> 10) & 0x1f) == 0x1f) && (a & 0x3ff);
}
bool is_inf(const half a) {
return (((a >> 10) & 0x1f) == 0x1f) && !(a & 0x3ff);
}
float half2float(const half a) {
const auto f = (static_cast<std::uint32_t>(a & 0x8000) << 16) | (static_cast<std::uint32_t>(((a >> 10) & 0x1f) + 127 - 1023) << 23) | (static_cast<std::uint32_t>(a & 0x3ff) << 13);
return *reinterpret_cast<const float*>(&f);
}
half float2half(const float a) {
const auto b = *reinterpret_cast<const std::uint32_t*>(&a);
const auto h = static_cast<std::uint16_t>((b & 0x80000000) >> 16) | static_cast<std::uint16_t>((((b >> 23) & 0xff) + 1023 - 127) << 10) | (static_cast<std::uint16_t>(b >> 13) & 0x3ff);
return h;
}
int main(int argc, char** argv) {
const float nan = NAN;
//const float nan = INFINITY;
const auto nan_h = float2half(nan);
std::printf("nan = %e\n", nan);
std::printf("han_h = 0x%04hx\n", nan_h);
if (is_nan(nan_h)) {
std::cout<< "NaN" <<std::endl;
}
if (is_inf(nan_h)) {
std::cout<< "inf" <<std::endl;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment