将十六进制转换为浮点数时出错

Tan*_*rov 2 java floating-point android hex

我正在尝试在 Android 中转换此十六进制值C2DE70A4。这是我为转换编写的代码:

try {
        String hexString = "C2DE70A4";
        float myFloat = Float.intBitsToFloat(Integer.parseInt(hexString, 16));
    }

catch (Exception e) {
        Toast.makeText(getApplicationContext(),e.getMessage(),Toast.LENGTH_LONG).show();
    }
Run Code Online (Sandbox Code Playgroud)

但它导致异常并告诉我Invalid int: "C2DE70A4"

谁能帮我进行转换?浮点值应为:-111.22

谢谢。

ysh*_*vit 5

0xC2DE70A4 的十进制数为 3,269,357,732,但 int 的最大值为 2,147,483,647。这就是为什么你无法解析它——解析后的值太大,无法放入 int 中。

您应该将字符串解析为 long ,然后将其转换为 int ,最后调用Float.intBitsToFloat它:

long asLong = Long.parseLong(hexString, 16);
int asInt = (int) asLong;
float myFloat = Float.intBitsToFloat(asInt);
// or, just
float myFloat = Float.intBitsToFloat((int)Long.parseLong(hexString, 16));
Run Code Online (Sandbox Code Playgroud)

详细解释:

从根本上来说,问题在于 C2DE70A4 表示无符号值,而 Java 中的 int 是有符号的。如果您将其解析为 long,然后查看其位(通过Long.toBinaryString),您将看到:

11000010110111100111000010100100
Run Code Online (Sandbox Code Playgroud)

这是一个 32 长度的字符串,因为toBinaryString省略了前导 0。那么为什么它不适合 32 位 int 呢?因为上面的二进制字符串代表一个无符号数。或者,更准确地说,它实际上是这个带符号的 64 位二进制补码数的简写:

0000000000000000000000000000000011000010110111100111000010100100
Run Code Online (Sandbox Code Playgroud)

... 等于十进制的 3269357732,这超出了 an 的范围,int因为 anint有符号,这意味着最左边的数字是符号,而不是数字大小的一部分(即它有多大)。

如果你将其long转换为 an int,它会丢弃最左边的 32 位数字,留下一个 32 位 int 11000010110111100111000010100100——它对应于十进制的 -1025609564 (同样是二进制补码)。如果您随后将该数字输入到intBitsToFloat,您将得到 -111.22。