java 应用于字节变量的无符号右移行为
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3948220/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Behaviour of unsigned right shift applied to byte variable
提问by Radheshyam Nayak
Consider the following snip of java code
考虑下面的java代码片段
byte b=(byte) 0xf1;
byte c=(byte)(b>>4);
byte d=(byte) (b>>>4);
output:
输出:
c=0xff
d=0xff
expected output:
预期输出:
c=0x0f
how?
as b in binary 1111 0001
after unsigned right shift 0000 1111
hence 0x0f
but why is it 0xff
how?
如何?作为 b 在1111 0001
无符号右移后的二进制0000 1111
因此0x0f
但为什么是这样0xff
?
回答by starblue
The problem is that all arguments are first promoted to int
before the shift operation takes place:
问题是int
在移位操作发生之前首先提升所有参数:
byte b = (byte) 0xf1;
b
is signed, so its value is -15.
b
是有符号的,所以它的值为 -15。
byte c = (byte) (b >> 4);
b
is first sign-extended to the integer -15 = 0xfffffff1
, then shifted right to 0xffffffff
and truncated to 0xff
by the cast to byte
.
b
首先符号扩展到整数-15 = 0xfffffff1
,然后右移到0xffffffff
并通过强制转换截断0xff
到byte
。
byte d = (byte) (b >>> 4);
b
is first sign-extended to the integer -15 = 0xfffffff1
, then shifted right to 0x0fffffff
and truncated to 0xff
by the cast to byte
.
b
首先符号扩展到整数-15 = 0xfffffff1
,然后右移到0x0fffffff
并通过强制转换截断0xff
到byte
。
You can do (b & 0xff) >>> 4
to get the desired effect.
您可以这样做(b & 0xff) >>> 4
以获得所需的效果。
回答by CodesInChaos
I'd guess that b
is sign extended to int
before shifting.
我猜这b
是int
在转移之前扩展到的符号。
So this might work as expected:
所以这可能会按预期工作:
(byte)((0x000000FF & b)>>4)
回答by Progman
According to Bitwise and Bit Shift Operators:
根据按位和位移运算符:
The unsigned right shift operator ">>>" shifts a zero into the leftmost position, while the leftmost position after ">>" depends on sign extension.
无符号右移运算符“>>>”将零移到最左边的位置,而“>>”之后的最左边位置取决于符号扩展。
So with b >> 4
you transform 1111 0001
to 1111 1111
(b is negative, so it appends 1
) which is 0xff
.
所以随着b >> 4
你转换1111 0001
为1111 1111
(b 是负数,所以它附加1
) 是0xff
。
回答by soru
Java tries to skimp on having explicit support for unsigned basic types by defining the two different shift operators instead.
Java 试图通过定义两个不同的移位运算符来显式支持无符号基本类型。
The question talks about unsigned right shift, but the examples does both (signed and unsigned), and shows the value of the signed shift (>>).
该问题讨论了无符号右移,但示例同时进行了(有符号和无符号),并显示了有符号移位 (>>) 的值。
Your calculations would be right for unsigned shift (>>>).
您的计算适用于无符号移位 (>>>)。
回答by Joe23
The byte operand is promoted to an int before the shift.
字节操作数在移位之前被提升为 int。
See https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.19
请参阅https://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.19
Unary numeric promotion (§5.6.1) is performed on each operand separately. (Binary numeric promotion (§5.6.2) is not performed on the operands.)
一元数值提升(第 5.6.1 节)分别对每个操作数执行。(二进制数字提升(第 5.6.2 节)不在操作数上执行。)
And https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.1
和https://docs.oracle.com/javase/specs/jls/se7/html/jls-5.html#jls-5.6.1
Otherwise, if the operand is of compile-time type byte, short, or char, it is promoted to a value of type int by a widening primitive conversion (§5.1.2).
否则,如果操作数是编译时类型的 byte、short 或 char,则通过扩展原始转换(第 5.1.2 节)将其提升为 int 类型的值。
回答by user3898882
byte b=(byte) 0xf1;
字节b=(字节)0xf1;
if (b<0)
如果 (b<0)
d = (byte) ((byte) ((byte)(b>>1)&(byte)(0x7F)) >>>3);
d = (byte) ((byte) ((byte)(b>>1)&(byte)(0x7F)) >>>3);
else
别的
d = (byte)(b>>>4);
d = (字节)(b>>>4);
First, check the value: If the value is negative. Make one right shift, then & 0x7F, It will be changed to positive. then you can make the rest of right shift (4-1=3) easily.
首先,检查值:如果值为负。右移一格,然后&0x7F,就变成正数了。那么你可以轻松地进行其余的右移(4-1=3)。
If the value is positive, make all right shift with >>4 or >>>4. It does'nt make no difference in result nor any problem of right shift.
如果值为正,则用 >>4 或 >>>4 右移。它对结果没有任何影响,也没有任何右移问题。