Java 中的 >>>
和 >>
运算符有什么区别?
>>
是算术右移,>>>
是逻辑右移。
在算术移位中,符号位被扩展以保持数字的符号性。
例如:-2 用 8 位表示将是 11111110
(因为最高有效位具有负权重)。使用算术移位将其右移一位将得到 11111111
,或 -1。然而,逻辑右移并不关心该值是否可能表示一个有符号数。它只是将所有内容向右移动并从左侧填充 0。使用逻辑移位将我们的 -2 右移一位将得到 01111111
。
>>>
是无符号移位;它将插入 0。>>
已签名,并将扩展符号位。
JLS 15.19 移位运算符
移位运算符包括左移<<、有符号右移>>和无符号右移>>>。 n>>s 的值是带有符号扩展的 n 右移 s 位位置。 n>>>s 的值是 n 右移 s 位位置,零扩展。
System.out.println(Integer.toBinaryString(-1));
// prints "11111111111111111111111111111111"
System.out.println(Integer.toBinaryString(-1 >> 16));
// prints "11111111111111111111111111111111"
System.out.println(Integer.toBinaryString(-1 >>> 16));
// prints "1111111111111111"
为了让事情更清楚,添加积极的对应物
System.out.println(Integer.toBinaryString(121));
// prints "1111001"
System.out.println(Integer.toBinaryString(121 >> 1));
// prints "111100"
System.out.println(Integer.toBinaryString(121 >>> 1));
// prints "111100"
由于它是正数,有符号和无符号移位都会在最左边添加 0。
相关问题
右移执行除以 2 On -1
移位比Java中的乘法和除法更快吗? 。网?
什么是 c/c++ 等效的在 java 中执行 '>>>' 的方法(无符号右移)
负逻辑移位
Java 的 >> 与 >>> 运算符?
Java 运算符 >> 和 >>> 有什么区别?
>>> 和 >> 运算符之间的区别
像 C#/Java 这样的高级语言屏蔽位移计数操作数的原因是什么? 1 >>> 32 == 1
>>> 32 == 1
>>>
将始终在最左边放置一个 0,而 >>
将放置一个 1 或 0,具体取决于它的符号。
它们都是右移,但 >>>
是 unsigned
无符号右移运算符“>>>”将零移到最左边的位置,而“>>”之后的最左边的位置取决于符号扩展。
>>>
是无符号的,但为什么 7>>32=7
呢?我运行了一个循环,一次换一个班次,发现在 32
个班次之后,它又回到了 7
。唯一有意义的方法是,对于每个移出的数字,它都会进入一个“外圈”。在 32
移动之后,它以某种方式回到了它的位置,但显然这仍然没有意义。到底是怎么回事?
for (int i = 7 << 1, j = 0; j < 32; j++) System.out.println(Integer.toString(i >>= 1, 2));
) 如果您的意思是为什么 >>32
本身返回原始值,请参阅 this。
逻辑右移 (v >>> n
) 返回一个值,其中 v
中的位已右移 n
个位位置,0 从左侧移入。考虑移位 8 位值,用二进制编写:
01111111 >>> 2 = 00011111
10000000 >>> 2 = 00100000
如果我们将这些位解释为无符号非负整数,则逻辑右移具有将数字除以相应 2 的幂的效果。但是,如果数字采用二进制补码表示,则逻辑右移不会正确除以负数.例如,当这些位被解释为无符号数时,上面的第二次右移将 128 移位到 32。但它会从 -128 转移到 32,这在 Java 中很典型,这些位被解释为二进制补码。
因此,如果要进行移位以除以 2 的幂,则需要算术右移 (v >> n
)。它返回一个值,其中 v
中的位已向右移动了 n
个位,并且 v 的最左侧位 的副本从左侧移入:
01111111 >> 2 = 00011111
10000000 >> 2 = 11100000
当位是二进制补码表示的数字时,算术右移具有除以 2 的幂的效果。这是有效的,因为最左边的位是符号位。除以二的幂必须保持符号相同。
详细了解Bitwise and Bit Shift Operators
>> Signed right shift
>>> Unsigned right shift
位模式由左侧操作数给出,而要移位的位置数由右侧操作数给出。无符号右移运算符 >>>
将 零 移到最左边的位置,
而 >>
之后的最左边位置取决于符号扩展。
简单来说,>>>
总是将 零 移到最左边的位置,而 >>
根据数字的符号进行移动,即 1 表示负数,0 表示正数。
例如,尝试使用负数和正数。
int c = -153;
System.out.printf("%32s%n",Integer.toBinaryString(c >>= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c >>>= 2));
System.out.println(Integer.toBinaryString(c <<= 2));
System.out.println();
c = 153;
System.out.printf("%32s%n",Integer.toBinaryString(c >>= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c >>>= 2));
System.out.printf("%32s%n",Integer.toBinaryString(c <<= 2));
输出:
11111111111111111111111111011001
11111111111111111111111101100100
111111111111111111111111011001
11111111111111111111111101100100
100110
10011000
100110
10011000
System.out.println(Integer.MAX_VALUE + ": " + String.format("%32s", Integer.toBinaryString(Integer.MAX_VALUE)).replace(' ', '0'))
; Integer.MAX_VALUE:01111111111111111111111111111111;
Integer.MIN_VALUE:10000000000000000000000000000000;
-1:11111111111111111111111111111111;
0: 00000000000000000000000000000000;
1:00000000000000000000000000000001
右移逻辑运算符 (>>> N
) 将位向右移动 N 个位置,丢弃符号位并用 0 填充最左边的 N 个位。例如:
-1 (in 32-bit): 11111111111111111111111111111111
>>> 1
操作后变为:
2147483647: 01111111111111111111111111111111
右移算术运算符 (>> N
) 也将位向右移动 N 个位置,但保留符号位并用 1 填充最左边的 N 个位。例如:
-2 (in 32-bit): 11111111111111111111111111111110
>> 1
操作后变为:
-1: 11111111111111111111111111111111
2^k
,但我觉得奇怪的是这是每个人的答案。位串不是数字,>>
始终可以用于任何位串:无论位串所扮演的角色如何,也不管它是否具有 ' 的概念,它总是做同样的事情符号'。当您的操作数 not 被解释为有符号数字时,可以通过讨论这种情况来扩展您已经很好的答案吗?我的抱怨有意义吗?String
也可以被视为char[]
。他并不是说char
不是数字;他只是说这是一个无符号数字。我想这就是他迷路的地方。