-1

在阅读了有关位移/屏蔽的所有问题和答案后,我根本无法理解它。我只是不了解它在基本层面上是如何工作的。我已经能够通过使用 BitArray 和 BitConverter 来实现各种技术,但我真的很想更好地理解位移/屏蔽。

我的具体需要是执行以下操作:

我有一个 ushort:0x810E (33038)

使用位移/屏蔽,我想知道如何:

  • 获取第 16 位结果:1
  • 获取第 15 位结果:0
  • 获取一系列位以创建新的 ushort 值,特别是前 14 位结果:270

正如我所说,我能够使用 BitArray 执行这些任务,这就是我获得正确结果的方式,但我想了解如何使用位移/屏蔽来执行这些操作。

任何帮助,将不胜感激。

4

1 回答 1

3

屏蔽单个位

您可能知道,ushort是一个 16 位的值,因此您给定的数字0x810E也可以写为

‭10000001 00001110‬

因为 没有移位运算符ushort,所以首先将值转换为int

所以,如果你想得到第 15 位,你可以拿一个位

000000000 0000000 00000000 00000001

并将其向左移动 14 次(右侧填充0

00000000 00000000 01000000 00000000

并且您已经创建了一个位掩码

现在,如果您将 mask 和 value 与 bitwise 结合起来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)并执行一个简单的按位&with 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);

其中 (0xFFFF00000000 00000000 11111111 11111111)。

于 2017-04-20T05:48:09.117 回答