当前位置: 首页 > 面试题库 >

Java将int转换为字节时的奇怪行为?

汪晨
2023-03-14
问题内容
int i =132;

byte b =(byte)i; System.out.println(b);

令人难以置信。为什么输出-124?


问题答案:

在Java中,an int是32位。A byte是8 bits

最原始的类型Java中的签名,byteshortint,和long被编码在二进制补码。(char类型为unsigned,并且sign的概念不适用于boolean。)

在此数字方案中,最高有效位指定数字的符号。如果需要更多位,则将最高有效位(“ MSB”)简单复制到新的MSB中。

因此,如果你具有byte 255:11111111 并将其表示为int 32位,则只需将1复制到左侧24次。

现在,读取负数2的补码的一种方法是从最低有效位开始,向左移动直到找到第一个1,然后再将每一位取反。结果数字是该数字的正数

例如:11111111转到00000001= -1。这就是Java将显示为值的内容。

你可能想做的是知道字节的无符号值。

你可以使用位掩码完成此操作,该位掩码将删除除最低有效8位之外的所有内容。(0xff)

所以:

byte signedByte = -1;
int unsignedByte = signedByte & (0xff);

System.out.println("Signed: " + signedByte + " Unsigned: " + unsignedByte);

将打印出: “Signed: -1 Unsigned: 255”

这里到底发生了什么?

我们使用按位AND来掩盖所有无关的符号位(最低有效8位左侧的1。)将int转换为字节时,Java砍掉最左侧的24位

1111111111111111111111111010101
&
0000000000000000000000001111111
=
0000000000000000000000001010101

由于现在第32位是符号位,而不是第8位(并且我们将符号位设置为0,这是正数),因此Java读取字节中的原始8位作为正值。



 类似资料:
  • 我遇到了奇怪的问题时,铸造小数到双倍。 以下代码返回true: 但是,当我将其强制转换为双倍时,它返回false: 这是记录在案的行为吗?当我被迫将decimal转换为Double时,我如何避免它? Visual Studio的截图: 将Math.round铸造为双倍me,结果如下: null 不幸的是,我不能在较小的项目中重现这个问题。我想埃里克的回答解释了原因。

  • 问题内容: 我将开始处理需要读取字节并创建字符串的内容。读取的字节代表UTF-16字符串。因此,为了进行测试,我想将UTF-16编码的简单字节数组转换为字符串。数组中的前2个字节必须表示字节序,因此必须为0xff 0xfe或0xfe 0xff。所以我尝试如下创建字节数组: 但是我收到一个错误,因为0xFF和0xFE太大而无法容纳一个字节(因为字节是用Java签名的)。更准确地说,错误是int无法转

  • 问题内容: 我需要将缓冲区的长度存储在4个字节大的字节数组中。 伪代码: 做到这一点的最佳方法是什么?请记住,稍后我必须将该字节数组转换回整数。 问题答案: 您可以使用以下方式将其转换为字节: 注意,这样做时可能必须考虑字节顺序。

  • 我目前正在处理一些小的endian二进制数据,我已经到了一个尴尬的地步,需要将奇数字节转换成整数值。 现在使用类,我能够很好地使用函数读取int和long,它们分别读取4和8个字节。 然而,在本例中,我需要读取三个字节,并将它们转换为int。我尝试过使用(2字节1字节),但我认为这不是正确的方法。 我猜我需要对字节进行位移位才能得到正确的int值,但我总是对位移位感到困惑。 此外,我还以为字节缓冲

  • 问题内容: 这个问题已经在这里有了答案 : 为什么对泛型的这种使用不会引发运行时或编译时异常? (3个答案) 2年前关闭。 我正在使用Java 8。 我最近遇到了这个问题: 这不会引发java.lang.ClassCastException。这是为什么? 我一直在想和打电话。但是,当我尝试这样做时,它会按预期抛出异常。 问题答案: 它不会抛出,因为所有通用类型信息都已从编译后的代码中剥离(此过程称

  • 我构建了一个小函数来将TimeStamp转换成LocalDate,并偶然发现了奇怪的行为。下面是代码: 我当地的时区是欧洲/柏林。现在,当调用时间戳0时,我得到正确的结果: 一切如期而至。但当我把它命名为第一年的日期时,它辜负了我的期望: 问题: 转换为Instant后缺少一天,所以UTC和欧洲/柏林的时区似乎在当时相隔一天加一小时