» exact float conversion

Wednesday, 28 November A.D. 2012 @ 10:11 PM

Somebody at work asked how to determine whether an integer (assuming to be 32-bit) was exactly convertable into a (IEEE single) float. There's the obvious:

bool
exactly_convertable_p (int32_t x)
{
  float f = x;
  int y = f;
  return x == y;
}

but it's more fun to reason things out from first principles. The __builtin_ctz call below is GCC-specific, but it should be straightforward to write your own ctz function:

bool
exactly_convertable_p (int32_t x)
{
  /* The easy cases: an exponent of 0 and mantissa of the integer.  */
  if ((-1 << 24) <= x && x <= (1 << 24))
    return true;

  /* Count trailing zeros and see if we can use a non-zero exponent.  */
  int first_low_bit = __builtin_ctz(x);
  if (first_low_bit == 0) {
    return false;
  }

  int32_t shifted = x >> first_low_bit;
  return (-1 << 24) <= shifted && shifted <= (1 << 24);
}

It should be fairly obvious how to extend this to 64-bit integers and IEEE double floats. Bonus points for doing a templated solution that works for given integer and float types.