gex*_*ide 5 c c++ java bit-manipulation bit-shift
我偶然发现了一个问题,询问你是否曾经不得不在实际项目中使用位移.我在许多项目中都使用了相当广泛的位移,但是,我从来不必使用算术位移,即位移,其中左操作数可能是负的,符号位应该移位而不是零.例如,在Java中,您将使用运算>>符进行算术位移(同时>>>执行逻辑移位).在经过深思熟虑之后,我得出的结论是,我从未使用>>过可能为负的左操作数.
正如本回答中所述,算术移位甚至是在C++中定义的实现,因此与Java相比 - 在C++中甚至没有用于执行算术移位的标准化运算符.答案还说明了一个有趣的问题,我甚至都没有意识到负面数字的变化:
+63 >> 1 = +31 (integral part of quotient E1/2E2)
00111111 >> 1 = 00011111
-63 >> 1 = -32
11000001 >> 1 = 11100000
Run Code Online (Sandbox Code Playgroud)
因此,当看到这些位时,-63>>1收益率-32是显而易见的,但也许不是大多数程序员一见钟情的预期.更令人惊讶的是(但在查看位时再次显而易见)-1>>1是-1,不是0.
那么,可能负值算术右移的具体用例是什么?
也许最着名的是无分支绝对值:
int m = x >> 31;
int abs = x + m ^ m;
Run Code Online (Sandbox Code Playgroud)
它使用算术移位将signbit复制到所有位.我遇到的大多数算术移位用途都是那种形式.当然,对此不需要算术移位,您可以替换所有出现的x >> 31(where xis a int)-(x >>> 31).
值31来自int以位为单位的大小,在Java中定义为32.因此,向右移位31会移除除符号位之外的所有位,因为它(因为它是算术移位)被复制到那些31位,在每个位置留下一个符号位的副本.
它以前对我来说很有用,可以创建随后用于“&”或“|”的蒙版。操作位字段时的运算符,无论是按位数据打包还是按位图形。
我没有方便的代码示例,但我确实记得多年前在黑白图形中使用该技术来放大(通过扩展一点,1 或 0)。对于 3 倍变焦,“0”将变为“000”,“1”将变为“111”,而无需知道该位的初始值。要扩展的位将被放置在高位位置,然后算术右移将扩展它,无论它是 0 还是 1。逻辑移位,无论是左移还是右移,总是引入零来填充空出的位位置。在这种情况下,符号位是解决方案的关键。
| 归档时间: |
|
| 查看次数: |
1088 次 |
| 最近记录: |