Java中的字节默认是签名的。我在其他帖子上看到,使用无符号字节的解决方法类似于:int num = (int) bite & 0xFF
有人可以向我解释为什么会这样,并将有符号字节转换为无符号字节然后转换为相应的整数? ANDing
一个字节与11111111产生相同的字节 - 对吗?
答案 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添加到负字节。