1. 概述

在本篇文章中,我们将探讨如何使用 Java 实现 float 类型与字节数组之间的相互转换。

对于整型(如 intlong)来说,这种转换较为直接,因为 Java 的位运算操作本身就是针对整型设计的。但 float 是浮点数类型,处理起来需要额外的步骤。

为此,我们可以借助 Float 类提供的方法,或者使用 java.nio 包中的 ByteBuffer 来完成转换。

2. Float 转字节数组

我们知道,在 Java 中一个 float 占用 32 位,和 int 一样。因此可以通过 Float 类的 floatToIntBits()floatToRawIntBits() 方法先将其转为整数形式,再通过位移操作提取出各个字节。

这两个方法的区别在于:

  • floatToRawIntBits() 会保留 NaN 值的具体表示;
  • ❌ 而 floatToIntBits() 则会对某些特殊值进行规范化。

下面是使用 Float 类手动实现转换的代码:

public static byte[] floatToByteArray(float value) {
    int intBits =  Float.floatToIntBits(value);
    return new byte[] {
      (byte) (intBits >> 24), (byte) (intBits >> 16), (byte) (intBits >> 8), (byte) (intBits) };
}

更简洁的方式是使用 ByteBuffer

ByteBuffer.allocate(4).putFloat(value).array();

这种方式简单粗暴,无需手动处理位移逻辑,强烈推荐使用。

3. 字节数组转 Float

将字节数组还原为 float 同样可以使用 Float.intBitsToFloat() 方法。不过在此之前,我们需要把四个字节重新组合成一个整数,这通常通过左移和按位或操作来完成:

public static float byteArrayToFloat(byte[] bytes) {
    int intBits = 
      bytes[0] << 24 | (bytes[1] & 0xFF) << 16 | (bytes[2] & 0xFF) << 8 | (bytes[3] & 0xFF);
    return Float.intBitsToFloat(intBits);  
}

⚠️ 注意:(bytes[i] & 0xFF) 是为了防止符号扩展带来的错误。

使用 ByteBuffer 的方式则更加直观:

ByteBuffer.wrap(bytes).getFloat();

一行搞定,谁用谁知道。

4. 单元测试示例

下面是一些简单的单元测试用例,用于验证上述转换逻辑是否正确:

@Test
public void givenAFloat_thenConvertToByteArray() {
    assertArrayEquals(new byte[] { 63, -116, -52, -51}, floatToByteArray(1.1f));
}

@Test
public void givenAByteArray_thenConvertToFloat() {
   assertEquals(1.1f, byteArrayToFloat(new byte[] { 63, -116, -52, -51}), 0);
}

这里需要注意的是浮点比较时要传入 delta 值(第三个参数),否则可能由于精度问题导致断言失败。

5. 总结

我们展示了多种在 float 和字节数组之间转换的方法:

  • 使用 Float 类的方法属于“曲线救国”,适合对底层原理感兴趣的开发者;
  • ByteBuffer 提供了更为优雅和现代的解决方案,建议优先采用。

完整的示例代码和测试用例可以在 GitHub 上找到:GitHub 项目地址


原始标题:Convert a Float to a Byte Array in Java