Skip to content

Instantly share code, notes, and snippets.

@cjlawson02
Last active July 25, 2019 20:10
Show Gist options
  • Save cjlawson02/0a8253b42d16f08962add44d9b6136e4 to your computer and use it in GitHub Desktop.
Save cjlawson02/0a8253b42d16f08962add44d9b6136e4 to your computer and use it in GitHub Desktop.
#include <iostream>
#include <cmath>
using namespace std;
float F16ConvertToF32(uint16_t f16)
{
float f32 = 0;
unsigned sign = (f16 & 0x8000) >> 15; //extract out the sign
unsigned exponent = ((f16 & 0x7C00) >> 10); //extract out the exponent
float fraction = (f16 & 0x03ff) / 1024.0; //extract out the fraction
//check for inf & NaN, 0x7F800000 = +inf 0xFF800000 = -inf
if (exponent == 0x1f)
{
if (fraction == 0)
{
int positveInf = 0x7f800000;
int negativeInf = 0xff800000;
return (sign == 0) ? *(float *)&positveInf : *(float *)&negativeInf;
}
else
{
return 0.0 / 0.0; //use 0.0 to generate NaN
}
}
//check for 0 or subnormal
if (exponent == 0)
{
if (fraction == 0)
{ // if it is 0
if (sign == 1)
return -0.0;
return 0.0; // use 0.0 to return a zero in float
}
else
{
f32 = fraction * pow(2.0, -14.0);
if (sign == 1)
f32 *= -1.0;
return f32;
}
}
//the number is not a NaN or 0 or subnormal
f32 = (fraction + 1.0) * pow(2.0, ((int)exponent - 15));
if (sign == 1)
f32 *= -1.0;
return f32;
}
int main(int argc, char **argv)
{
char *pCh;
unsigned long unlong = 42;
// Check enough arguments.
if (argc != 2)
{
cout << "Not enough arguments."
<< "\n";
return 1;
}
// Convert to ulong WITH CHECKING!
unlong = strtoul(argv[1], &pCh, 10);
// Ensure argument was okay.
if ((pCh == argv[1]) || (*pCh != '\0'))
{
cout << "Invalid number: " << argv[1]
<< "\n";
return 1;
}
// Output converted argument and exit.
cout << F16ConvertToF32(unlong);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment