java - 将十六进制转换为 float 时出错

标签 java android floating-point 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();
    }

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

任何人都可以帮助我进行转换吗? float 值应为:-111.22

谢谢。

最佳答案

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));

详细解释:

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

11000010110111100111000010100100

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

0000000000000000000000000000000011000010110111100111000010100100

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

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

关于java - 将十六进制转换为 float 时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33852281/

相关文章:

C思维: float vs.整数和浮点表示

java - 使用文件协议(protocol)在java中打开当前目录中的文件

java - 如何使用 XSLT 生成文本文件

java - Spring Android Framework - 通过 HTTP GET 检索 JSON 数据

android - Firebase - Android - fetchProvidersForEmail - 为什么所有调用都是异步的?

java - OpenCV Mat 处理时间

postgresql - 选择十进制形式的 float

java - 如何使用 Java 正则表达式验证几何点?

java - Nexus 模拟器屏幕不显示 maven android :deploy result

javascript float 比较