gpt4 book ai didi

java - 如何安全地将 Java 字节用作无符号字符?

转载 作者:搜寻专家 更新时间:2023-11-01 03:20:44 25 4
gpt4 key购买 nike

我正在将一些使用大量位操作的 C 代码移植到 Java 中。 C 代码在 int 为 32 位宽而 char 为 8 位宽的假设下运行。其中有断言可以检查这些假设是否有效。

我已经接受了我必须使用 long 代替 unsigned int 的事实。但是我可以安全地使用 byte 来替代 unsigned char 吗?

它们仅代表字节,但我已经遇到了这个奇怪的事件:(data 是 C 中的 unsigned char *byte[] 在 Java 中):

/* C */
uInt32 c = (data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3];

/* Java */
long a = ((data[0] << 24) | (data[1] << 16) | (data[2] << 8) | data[3]) & 0xffffffff;
long b = ((data[0] & 0xff) << 24) | ((data[1] & 0xff) << 16) |
((data[2] & 0xff) << 8) | (data[3] & 0xff) & 0xffffffff;

您会认为左移操作是安全的。但是由于 Java 中奇怪的一元提升规则,如果 data 中的某些字节是“负数”,ab 将不会相同"(b 给出了正确的结果)。

我应该注意哪些其他“陷阱”?我真的不想在这里使用 short

最佳答案

您可以安全地使用 byte 来表示 0 到 255 之间的值,前提是您在计算中使用它之前确保将其值与 255(或 0xFF)进行按位与运算。这会将其提升为 int,并确保提升后的值介于 0 和 255 之间。

否则,使用符号扩展,整数提升将导致 int 值介于 -128 和 127 之间。 -127 作为 byte(十六进制 0x81)将变为 -127 作为 int(十六进制 0xFFFFFF81)。

所以你可以这样做:

long a = (((data[0] & 255) << 24) | ((data[1] & 255) << 16) | ((data[2] & 255) << 8) | (data[3] & 255)) & 0xffffffff;

请注意,第一个 & 255 在这里是不必要的,因为后面的步骤无论如何都会屏蔽掉额外的位 (& 0xffffffff)。但始终包含它可能是最简单的。

关于java - 如何安全地将 Java 字节用作无符号字符?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31217201/

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