static float toFloat(Binary b) {
    short h = b.get2BytesLittleEndian();
    int bits = h & 0xffff;
    int s = bits & SIGN_MASK;
    int e = (bits >>> EXPONENT_SHIFT) & SHIFTED_EXPONENT_MASK;
    int m = (bits) & SIGNIFICAND_MASK;
    int outE = 0;
    int outM = 0;
    if (e == 0) { // Denormal or 0
      if (m != 0) {
        // Convert denorm fp16 into normalized fp32
        float o = Float.intBitsToFloat(FP32_DENORMAL_MAGIC + m);
        o -= FP32_DENORMAL_FLOAT;
        return s == 0 ? o : -o;
      }
    } else {
      outM = m << 13;
      if (e == 0x1f) { // Infinite or NaN
        outE = 0xff;
        if (outM != 0) { // SNaNs are quieted
          outM |= FP32_QNAN_MASK;
        }
      } else {
        outE = e - EXPONENT_BIAS + FP32_EXPONENT_BIAS;
      }
    }
    int out = (s << 16) | (outE << FP32_EXPONENT_SHIFT) | outM;
    return Float.intBitsToFloat(out);
  }
@Test
  public void testFloat16ToFloat() {
    // Zeroes
    assertEquals(0.0f, Float16.toFloat(Binary.fromConstantByteArray(new byte[] {0x00, 0x00})), 0.0f);
    assertEquals(-0.0f, Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x00, (byte) 0x80})), 0.0f);
    // NaN
    assertEquals(
        Float.NaN, Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0xc0, (byte) 0x7f})), 0.0f);
    assertEquals(
        Float.NaN, Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x00, (byte) 0x7e})), 0.0f);
    assertEquals(
        Float.NaN, Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x00, (byte) 0x7f})), 0.0f);
    assertEquals(
        Float.NaN, Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x00, (byte) 0xfe})), 0.0f);
    assertEquals(
        Float.NaN, Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x00, (byte) 0xff})), 0.0f);
    assertEquals(
        Float.NaN, Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x7f, (byte) 0x7e})), 0.0f);
    assertEquals(
        Float.NaN, Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x7f, (byte) 0xfe})), 0.0f);
    assertEquals(
        Float.NaN, Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0xff, (byte) 0xfe})), 0.0f);
    assertEquals(
        Float.NaN, Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0xff, (byte) 0x7f})), 0.0f);
    assertEquals(
        Float.NaN, Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0xff, (byte) 0xff})), 0.0f);
    // infinities
    assertEquals(
        Float.POSITIVE_INFINITY,
        Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x00, (byte) 0x7c})),
        0.0f);
    assertEquals(
        Float.NEGATIVE_INFINITY,
        Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x00, (byte) 0xfc})),
        0.0f);
    // subnormals
    assertEquals(
        5.9604645E-8f,
        Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x01, (byte) 0x00})),
        0.0f);
    assertEquals(
        -65504.0f, Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0xff, (byte) 0xfb})), 0.0f);
    assertEquals(
        +65504.0f, Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0xff, (byte) 0x7b})), 0.0f);
    assertEquals(
        -6.097555E-5f,
        Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0xff, (byte) 0x83})),
        0.0f);
    assertEquals(
        -5.9604645E-8f,
        Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x01, (byte) 0x80})),
        0.0f);
    // Known values
    assertEquals(
        1.0009765625f,
        Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x01, (byte) 0x3c})),
        0.0f);
    assertEquals(-2.0f, Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x00, (byte) 0xc0})), 0.0f);
    assertEquals(
        6.1035156e-5f,
        Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x00, (byte) 0x04})),
        0.0f); // Inexact
    assertEquals(
        65504.0f, Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0xff, (byte) 0x7b})), 0.0f);
    assertEquals(
        0.33325195f,
        Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x55, (byte) 0x35})),
        0.0f); // Inexact
    // Denormals (flushed to +/-0)
    assertEquals(
        6.097555e-5f,
        Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0xff, (byte) 0x03})),
        0.0f);
    assertEquals(
        5.9604645e-8f,
        Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x01, (byte) 0x00})),
        0.0f); // Inexact
    assertEquals(
        -6.097555e-5f,
        Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0xff, (byte) 0x83})),
        0.0f);
    assertEquals(
        -5.9604645e-8f,
        Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x01, (byte) 0x80})),
        0.0f); // Inexact
    // Miscellaneous values. In general, they're chosen to test the sign/exponent and
    // exponent/mantissa boundaries
    assertEquals(
        +0.00050163269043f,
        Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x1c, (byte) 0x10})),
        0.0f);
    assertEquals(
        -0.00050163269043f,
        Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x1c, (byte) 0x90})),
        0.0f);
    assertEquals(
        +0.000502109527588f,
        Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x1d, (byte) 0x10})),
        0.0f);
    assertEquals(
        -0.000502109527588f,
        Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x1d, (byte) 0x90})),
        0.0f);
    assertEquals(
        +0.00074577331543f,
        Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x1c, (byte) 0x12})),
        0.0f);
    assertEquals(
        -0.00074577331543f,
        Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x1c, (byte) 0x92})),
        0.0f);
    assertEquals(
        +0.00100326538086f,
        Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x1c, (byte) 0x14})),
        0.0f);
    assertEquals(
        -0.00100326538086f,
        Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x1c, (byte) 0x94})),
        0.0f);
    assertEquals(
        +32.875f, Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x1c, (byte) 0x50})), 0.0f);
    assertEquals(
        -32.875f, Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x1c, (byte) 0xd0})), 0.0f);
    // A few subnormals for good measure
    assertEquals(
        +1.66893005371e-06f,
        Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x1c, (byte) 0x00})),
        0.0f);
    assertEquals(
        -1.66893005371e-06f,
        Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x1c, (byte) 0x80})),
        0.0f);
    assertEquals(
        +3.21865081787e-05f,
        Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x1c, (byte) 0x02})),
        0.0f);
    assertEquals(
        -3.21865081787e-05f,
        Float16.toFloat(Binary.fromConstantByteArray(new byte[] {(byte) 0x1c, (byte) 0x82})),
        0.0f);
  }