gpt4 book ai didi

Java Byte[] 到 int (Big Endian) 使用 << Weirdness

转载 作者:行者123 更新时间:2023-11-29 05:22:36 25 4
gpt4 key购买 nike

假设我们有以下字节[4]:

44 a4 8a c6

那么下面的代码哪里出了问题:

public static int asIntBigEndian(byte[] raw, int offset){
int result = 0;
for(int i=offset; i<offset+4; ++i){
result = (result << 4) | raw[i];
}
return result;
}

调用 asIntBigEndian(raw, 0) 的结果是:

ff ff ff e6

我注意到,如果我要读取第一个字节并将其打印出来,我会得到:

44

如果我这样做,我会得到相同的结果:

System.out.println(Integer.toHexString(raw[0] << 24));

0x44000000

所以如果我继续这个逻辑......

System.out.println(Integer.toHexString( (raw[0] << 24)|(raw[1] << 16) );

0xffa40000

基本上第一个字节变成了 0xff 而第二个字节 0xa4 已经被“异或”到正确的位置。为什么会这样?

最佳答案

byte Java 中的 s 的范围从 -128 (-0x80) 到 127 (0x7F)。 164 (0xA4) 不是有效值,但“A4”是您通过打印 -92 (-0x5C) 得到的,就好像它是无符号的。

将 -0x5C 转换为 int还给出 -0x0000005C。 -0x0000005C,打印为无符号,是0xFFFFFFA4。

另一种可能更简单的思考方式是将所有值都视为无符号,但将转换视为符号扩展 - 其中最高位被复制到所有新位中。如果你这样想,0xA4 是一个有效字节,(int)0xA4 就是 0xFFFFFFA4。结果相同,思考过程更简单,但在 Java 中思考数字的方式不太正确(但这并没有什么不同)。

0xFFFFFFA4 << 16给出 0xFFA400000x44000000 | 0xFFA40000给出 0xFFA40000 - 这就是您获得该结果的方式。

修复很简单 - 而不是 raw[i] , 使用 ((int)raw[i] & 0xFF) , 或者只是 (raw[i] & 0xFF)作为转换为 int是隐式的。

此外,与该问题无关,(result << 4)应该是 (result << 8) .否则你正在计算 0x44000 | 0xA400 | 0x8A0 | 0xC6而不是 0x44000000 | 0xA40000 | 0x8A00 | 0xC6 .

关于Java Byte[] 到 int (Big Endian) 使用 << Weirdness,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24074312/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com