在阅读了所有关于位移/屏蔽的问题和答案后,我根本无法理解它。 我只是不明白它在基本层面上是如何工作的。 我已经能够通过使用BitArray和BitConverter来实现各种技术,但我真的很想更好地理解位移/屏蔽。
我的具体需求是执行以下操作:
我有一个短裤:0x810E(33038)
使用位移/屏蔽,我想知道如何:
- 获取第 16 位结果:1
- 获取第 15 位结果:0
- 获取一系列位以创建新的 ushort 值,特别是 前 14 位结果:270
正如我所说,我能够使用 BitArray 执行这些任务,这就是我获得正确结果的方式,但我想了解如何使用位移/掩码来执行这些操作。
任何帮助将不胜感激。
屏蔽单个位
您可能知道,ushort
是一个 16 位值,因此您给定的数字0x810E
也可以写为
10000001 00001110
因为ushort
没有移位运算符,所以该值首先转换为int
。
所以,如果你想得到第15位,你可以取一个位
000000000 0000000 00000000 00000001
并向左移动14次(右侧充满0
)
00000000 00000000 01000000 00000000
并且您已经创建了一个位掩码。
现在,如果将掩码和值与按位and
结合使用,则只会得到第 15 位的值:
00000000 00000000 10000001 00001110
& 00000000 00000000 01000000 00000000
= 00000000 00000000 00000000 00000000
这又0
了。要访问此位,您必须将整个结果移回右侧 14 次并将其转换为ushort
.
这可以用以下代码表示:
ushort value_15 = (ushort)(((1 << 14) & value) >> 14);
我们能做得更好吗?
虽然这种方法看起来是正确的,但有一个更简单的方法可以做到这一点:将原始值向右移动 14 次 (结果是00000000 00000000 00000000 00000010
,左侧填充0
)并用1
执行简单的按位&
:
00000000 00000000 00000000 00000000 00000000 00000010
& 00000000 00000000 00000000 00000000 00000000 00000001
= 00000000 00000000 00000000 00000000 00000000 00000000
这会导致C#
:
ushort value_15 = (ushort)((value >> 14) & 1);
因此,您可以避免一个额外的班次,即使使用有符号数字(因为那里用于符号的最高位通过移位保持不变)。
屏蔽位范围
要屏蔽位范围,您所要做的就是更改掩码。因此,要获得较低 14 位的值,您可以使用掩码
00000000 00000000 10000001 00001110
& 00000000 00000000 00111111 11111111
= 00000000 00000000 00000001 00001110
C#
这可以用
ushort first14bits = (ushort)((0xFFFF >> 2) & value);
其中(0xFFFF
是00000000 00000000 11111111 11111111
)。