Java 为什么bit或操作将导致符号扩展,而bit和won';T
我需要在Java中将一个字节强制转换为int,但我不想要符号扩展,所以我这样做了Java 为什么bit或操作将导致符号扩展,而bit和won';T,java,bit-manipulation,Java,Bit Manipulation,我需要在Java中将一个字节强制转换为int,但我不想要符号扩展,所以我这样做了 byte b = -1 (int) (b & 0xF) // this returns 15, which is what I want (int) (b | 0) // this returns -1, which is essentially 0xFFFF, sign extension happens, not what I want 我认为上面两个应该给出相同的结果,但事实并非如此。 我必须在
byte b = -1
(int) (b & 0xF) // this returns 15, which is what I want
(int) (b | 0) // this returns -1, which is essentially 0xFFFF, sign extension happens, not what I want
我认为上面两个应该给出相同的结果,但事实并非如此。
我必须在位运算中漏掉一些东西。诀窍是打印这些值的二进制表示,并对它们执行二进制运算
byte b = -1;
int a = (int) (b & 0xF); // this returns 15, which is what I want
int c = (int) (b | 0); // this returns -1, which is essentially 0xFFFF
System.out.println("b:" + Integer.toBinaryString(b));
System.out.println("a:" + Integer.toBinaryString(a));
System.out.println("c:" + Integer.toBinaryString(c));
System.out.println("0xF:" + Integer.toBinaryString(0xF));
印刷品
b:11111111111111111111111111111111
a:1111
c:11111111111111111111111111111111
0xF:1111
所以b&OxF
是
11111111111111111111111111111111
00000000000000000000000000001111 (AND)
--------------------------------
1111 (15)
而b|0
11111111111111111111111111111111
00000000000000000000000000000000 (OR)
--------------------------------
11111111111111111111111111111111 (-1)
这里的问题是,按位运算符处理整数或长整数,而不是字节
b&0xF
基本上被视为((int)b)和((int)0xF)
。您可以从每个操作的JLS定义中进行跟踪
- 第一个(定义了
和&
)解释了当两个操作数都可转换为整数基元类型时,“首先对操作数执行二进制数字升级(§5.6.2)。”|
- 反过来说,除非任一操作数是
、浮点
或双精度
,否则这两个值都将加宽到长型
int
- 最后,在中定义了加宽,并指出“将有符号整数值的加宽转换为整数类型T simply sign扩展整数值的两个补表示以填充更宽的格式。”字节是有符号的()
b
字节在被右操作数AND'd或or'ed之前,使用符号扩展名被加宽为int
注意,这意味着b&0F
的结果应该是int
,而不是字节。事实上就是这样(这意味着显式将其强制转换为int
是多余的)。您可以通过将其自动装箱到对象
,然后检查该对象的类型来测试:
byte b = -1;
Object o = (b & 0xF);
System.out.println(o.getClass());
// prints "class java.lang.Integer", not "class java.lang.Byte"
用0
进行OR运算会得到另一个数字。这就是你要问的吗?不。我的意思是我认为0 |((字节)-1)应该是15,但实际上它是-1。用一个值对零进行排序会返回不变的值。Java的byte
是有符号的,所以当转换到int
@stevp时,你总是会得到符号扩展。它链接到HotLicks的评论。