java 十六进制字符串转换为有符号整数

String hexString = "FEF7"; // 十六进制字符串
int intValue = Integer.parseInt(hexString, 16); // 将十六进制字符串转换为整数
short signedValue = (short) intValue; // 转换为短整型(16位有符号整数)
int intValue = (bytes[1] & 0xFF) << 8 | (bytes[0] & 0xFF); // 合并两个字节为一个整数
return (short) ((intValue > 0x7FFF) ? (intValue - 0x10000) : intValue);

示例:0xF7FE代表-26.5

如果假设 0xFEF7 是一个带符号整数的补码,并且你希望将其转换为负数,那么需要执行以下步骤:

  1. 取反操作: 首先,对补码进行逐位取反操作,即将 0 变为 1,将 1 变为 0。

  2. 加 1: 在取反的结果上加 1。

这两个步骤合并起来,就是将补码取反后再加 1,得到原始的负数。以下是具体的计算过程示例:

假设 0xFEF7 是一个带符号整数的补码:

  1. 取反操作: 逐位取反得到 0x0108。

  2. 加 1: 在取反结果上加 1 得到 0x0109。

最终,原始的负数是 -265,与你之前提到的结果一致。请注意,这是假设 0xFEF7 是一个带符号整数的补码,实际情况可能需要更多上下文信息来确认。

方法解析:
intValue - 0x10000 的目的是将超出有符号短整数表示范围的值调整为在合法范围内。如果不执行减法操作,那么在以下情况下可能会发生问题:

假设你有一个带符号短整数的取值范围是 -32768 到 32767。如果 intValue 大于 32767,但你直接将其强制转换为 short,则会发生溢出。这是因为在 Java 中,整数溢出会导致循环,例如 32768 可能会变成 -32768,而 32769 可能会变成 -32767,依此类推。这不是你所期望的结果。

通过将 intValue 减去 0x10000,你实际上是在二进制中将高位的溢出部分减去,以使得值适应于有符号短整数的表示范围。这确保了正确的转换,并将溢出部分正确地移除,以得到合适的带符号短整数。

执行 intValue - 0x10000 是为了确保在转换过程中处理了可能的溢出情况,以便正确表示带符号短整数。

这个值之所以是 0x10000,是因为在 16 位表示中,最高位(最左边的位)表示的是符号位。在有符号短整数中,符号位为 1 时表示负数,为 0 时表示正数。所以,用一个 16 位的二进制数来表示有符号短整数,它的范围是从 -32768 到 32767。

当你希望将一个超出该范围的值转换为合法的带符号短整数时,你需要考虑如何修复溢出。通过减去 0x10000,你实际上是在处理二进制中的溢出情况。例如,如果你的值超过 32767,它的二进制表示的最高位将是 1,而带符号短整数的最大正值的二进制表示的最高位也是 1。这种情况下,通过减去 0x10000,你会将最高位的溢出部分减去,从而得到正确的带符号短整数。

posted @ 2023-08-02 19:54  zhaogaojian  阅读(641)  评论(0编辑  收藏  举报