#include <stdio.h>

unsigned int2hfloat(int x)
{
  unsigned sign = x < 0;
  unsigned absx = ((unsigned)x ^ -sign) + sign; // safe abs(x)
  unsigned tmp = absx, manbits = 0;
  int exp = 0, truncated = 0;

  // calculate the number of bits needed for the mantissa
  while (tmp)
  {
    tmp >>= 1;
    manbits++;
  }

  // round the number if necessary before we do the conversion
  if (manbits > 13)
    absx += (2<<(manbits-13));

  manbits = 0;
  tmp = absx;
  while (tmp)
  {
    tmp >>= 1;
    manbits++;
  }

  // half-precision floats have 11 bits in the mantissa.
  // truncate the excess or insert the lacking 0s until there are 11.
  if (manbits)
  {
    exp = 10; // exp bias because 1.0 is at bit position 10
    while (manbits > 11)
    {
      truncated |= absx & 1;
      absx >>= 1;
      manbits--;
      exp++;
    }
    while (manbits < 11)
    {
      absx <<= 1;
      manbits++;
      exp--;
    }
  }
  if (exp + truncated > 16)
  {
    // absx was too big, force it to +/- infinity
    exp = 31; // special infinity value
    absx = 0;
  }
  else if (manbits)
  {
    // normal case, absx > 0
    exp += 15; // bias the exponent
  }

  return (sign << 15) | ((unsigned)exp << 10) | (absx & ((1u<<10)-1));
}

int main(void)
{
  printf("+4095: 0x%04X\n", int2hfloat(+4095));
  printf("+4096: 0x%04X\n", int2hfloat(+4096));
  printf("+4097: 0x%04X\n", int2hfloat(+4097));
  printf("+4098: 0x%04X\n", int2hfloat(+4098));
  printf("+4099: 0x%04X\n", int2hfloat(+4099));
  printf("+2052: 0x%04X\n", int2hfloat(+2052));
  printf("+8190: 0x%04X\n", int2hfloat(+8190));
  printf("+8191: 0x%04X\n", int2hfloat(+8191));
  printf("+8192: 0x%04X\n", int2hfloat(+8192));
  printf("+8193: 0x%04X\n", int2hfloat(+8193));
  printf("+8194: 0x%04X\n", int2hfloat(+8194));
  printf("+8195: 0x%04X\n", int2hfloat(+8195));
  printf("+8196: 0x%04X\n", int2hfloat(+8196));
  printf("+8197: 0x%04X\n", int2hfloat(+8197));
  printf("+8198: 0x%04X\n", int2hfloat(+8198));
  printf("+8199: 0x%04X\n", int2hfloat(+8199));
  printf("+8200: 0x%04X\n", int2hfloat(+8200));
  printf("+16398: 0x%04X\n", int2hfloat(+16398));
  printf("+16400: 0x%04X\n", int2hfloat(+16400));
  printf("+32768: 0x%04X\n", int2hfloat(+32768));
  printf("+65504: 0x%04X\n", int2hfloat(+65504));
  printf("+65505: 0x%04X\n", int2hfloat(+65505));
  printf("+65519: 0x%04X\n", int2hfloat(+65519));
  printf("+65534: 0x%04X\n", int2hfloat(+65534));
  printf("+65535: 0x%04X\n", int2hfloat(+65535));
  printf("+65535: 0x%04X\n", int2hfloat(+65536));
  return 0;
}
