Java中的无符号字节

时间:2011-09-01 20:50:43

标签: java byte

Java中的字节默认是签名的。我在其他帖子上看到,使用无符号字节的解决方法类似于:int num = (int) bite & 0xFF

有人可以向我解释为什么会这样,并将有符号字节转换为无符号字节然后转换为相应的整数? ANDing一个字节与11111111产生相同的字节 - 对吗?

5 个答案:

答案 0 :(得分:25)

类型转换的优先级高于&运算符。因此,您首先要转换为int,然后进行AND运算以屏蔽所有设置的高位,包括java使用的两个补码表示法的“符号位”,只留下正值原始字节。 E.g:

let byte x = 11111111 = -1
then (int) x = 11111111 11111111 11111111 11111111
and x & 0xFF = 00000000 00000000 00000000 11111111 = 255

并且您已经有效地删除了原始字节中的符号。

答案 1 :(得分:15)

  

使用11111111对一个字节进行AND运算会产生相同的字节 - 对吗?

除非您与00000000000000000000000011111111进行AND运算,因为0xFF是int字面值 - Java中没有byte个字面值。那么会发生的是byte被提升为int(类型转换是不必要的),其符号被扩展(即保持byte的可能负值,但随后是符号扩展通过对所有这些零进行AND运算来恢复。结果是int的最低有效位与前byte完全相同,因此byte的值是无符号的

答案 2 :(得分:7)

在Java 8中,这种方法出现在Byte类中:

/**
 * Converts the argument to an {@code int} by an unsigned
 * conversion.  In an unsigned conversion to an {@code int}, the
 * high-order 24 bits of the {@code int} are zero and the
 * low-order 8 bits are equal to the bits of the {@code byte} argument.
 *
 * Consequently, zero and positive {@code byte} values are mapped
 * to a numerically equal {@code int} value and negative {@code
 * byte} values are mapped to an {@code int} value equal to the
 * input plus 2<sup>8</sup>.
 *
 * @param  x the value to convert to an unsigned {@code int}
 * @return the argument converted to {@code int} by an unsigned
 *         conversion
 * @since 1.8
 */
public static int toUnsignedInt(byte x) {
    return ((int) x) & 0xff;
}

答案 3 :(得分:2)

如您所见,结果是int而不是字节

它如何运作,比如我们有一个byte b = -128;,这表示为1000 0000,那么当你执行你的行时会发生什么?让我们使用temp int,比如说:
int i1 = (int)b; i1现在是-128,实际上这是用二进制表示的:

1111 1111 1111 1111 1111 1111 1000 0000

那么i1 & 0xFF在二进制文件中是什么样的?

1111 1111 1111 1111 1111 1111 1000 0000
&
0000 0000 0000 0000 0000 0000 1111 1111

导致

0000 0000 0000 0000 0000 0000 1000 0000

,这正好是128,这意味着您的签名值转换为无符号。

修改
将字节-128 .. 127转换为0 .. 255

int unsignedByte = 128 + yourByte;

您不能使用字节表示值128到255,您必须使用其他内容,如int或smallint。

答案 4 :(得分:0)

是的,但是这样你就可以确定你永远不会得到一个数>&gt; 255或&lt; 0。

如果第一位为1,则该数字为负数。如果将byte转换为int,如果为负,则将预先设置为1个字节,如果为正,则为0个字节。运行和例程将丢弃第一个8的剩余字节。这实际上将256添加到负字节。