我偶然发现了一个问题,询问是否 you ever had to use bit shifting in real projects .我在许多项目中广泛使用位移位,但是,我从来不必使用算术位移位,即左操作数可能为负且符号为负数的位移位应移入位而不是零。例如,在 Java 中,您可以使用 >>
进行算术位移。运算符(而 >>>
将执行逻辑移位)。想了很多,我得出的结论是我从来没有用过>>
。左操作数可能为负。
如 this answer 中所述算术移位甚至是在 C++ 中定义的实现,因此——与 Java 相比——C++ 中甚至没有用于执行算术移位的标准化运算符。答案还指出了一个我什至不知道的转移负数的有趣问题:
+63 >> 1 = +31 (integral part of quotient E1/2E2)
00111111 >> 1 = 00011111
-63 >> 1 = -32
11000001 >> 1 = 11100000
所以 -63>>1
产量 -32
这在查看这些位时是显而易见的,但也许不是大多数程序员第一眼所期望的。更令人惊讶(但在查看位时再次明显)是 -1>>1
是-1
, 不是 0
.
那么,可能负值的算术右移的具体用例是什么?
最佳答案
也许最著名的是无分支绝对值:
int m = x >> 31;
int abs = x + m ^ m;
它使用算术移位将符号位复制到所有位。我遇到的大多数算术移位都是这种形式。当然,为此不需要算术移位,您可以替换所有出现的 x >> 31
(其中 x
是一个 int
) 通过 -(x >>> 31)
。
值 31 来自 int
的大小(以位为单位),在 Java 中定义为 32。因此,右移 31 位会移出除符号位以外的所有位,符号位(因为它是算术移位)被复制到这 31 位,从而在每个位置留下符号位的拷贝。
关于java - 算术右移存在哪些实际用例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25056669/