c#-获取特定位并获取ushort值的前14位
在阅读了所有关于位移位/掩蔽的问题和答案后,我简直无法将我的头绕在它周围。我只是不理解它在基本层面上是如何工作的。我已经能够通过使用BitArray和BitConverter实现各种技术,但是我真的很想更好地理解位移位/掩蔽 我需要做的具体工作如下: 我有一个ushort:0x810E(33038) 使用位移位/掩蔽,我想知道如何:c#-获取特定位并获取ushort值的前14位,c#,bit-manipulation,bitmask,ushort,C#,Bit Manipulation,Bitmask,Ushort,在阅读了所有关于位移位/掩蔽的问题和答案后,我简直无法将我的头绕在它周围。我只是不理解它在基本层面上是如何工作的。我已经能够通过使用BitArray和BitConverter实现各种技术,但是我真的很想更好地理解位移位/掩蔽 我需要做的具体工作如下: 我有一个ushort:0x810E(33038) 使用位移位/掩蔽,我想知道如何: 获取第16位结果:1 获取第15位结果:0 获取一系列位以创建新的ushort值,特别是 前14位结果:270 正如我所说,我能够使用BitArray执行这些任
- 获取第16位结果:1
- 获取第15位结果:0
- 获取一系列位以创建新的ushort值,特别是 前14位结果:270
任何帮助都将不胜感激。屏蔽单个位 您可能知道,
ushort
是一个16位的值,因此给定的数字0x810E
也可以写成
10000001 00001110
由于ushort
没有移位运算符,因此该值首先转换为int
所以,如果你想得到第15位,你可以得到一个位
000000000 0000000 00000000 00000001
然后向左移动14次(右侧填充0
)
您已经创建了一个位掩码
现在,如果将掩码和值与按位的和组合,则只会得到第15位的值:
00000000 00000000 10000001 00001110
& 00000000 00000000 01000000 00000000
= 00000000 00000000 00000000 00000000
又是0
。要访问此位,您必须将整个结果向右移动14次,并将其转换为ushort
这可以用以下代码表示:
ushort value_15 = (ushort)(((1 << 14) & value) >> 14);
这将导致C#
in:
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
是00000000000000111111111111111111
)。Endianness在这里只是分散注意力。它与位掩蔽整数值无关,并且可能会让那些无法对位级操作进行研究的人感到困惑。语法和操作完全相同,无论单个整数值的长度是多少,也不管平台端号是多少。而且,在一个班次足够的情况下,做两班倒是一种浪费,一点也不“可以理解”。这只会使代码重复,更难阅读。此外,使用两个移位方法的场景可能会导致天真的程序员实现第二个移位,这可能会填充新的设置位(在这些场景中,另一种选择是强制转换,例如,1我已经删除了关于endianess的部分。我试图创建一个详尽的答案,但我承认,也许我关注的是不相关的细节。我现在时间不多了,也许我会稍后更改答案。我学到的一件事(因为我不知道)是强制转换。“强制转换是必需的”--是的,在这种情况下,因为预定义的运算符不包括一个用于ushort
,而隐式强制转换规则将ushort
强制转换为int
,而不是uint
,因此转换的结果是int
,并且必须强制转换回ushort
。类似于(ushort)(值>>15和1)`我真的很感谢你的解释。这对我帮助很大……直到彼得说有更好的单班制方法。我会接受这个答案,但是彼得,我希望你能跟进你的单班制答案,这样我们就能看到区别,并确定哪一个更好,更容易理解和阅读。谢谢大家!
00000000 00000000 10000001 00001110
& 00000000 00000000 00111111 11111111
= 00000000 00000000 00000001 00001110
ushort first14bits = (ushort)((0xFFFF >> 2) & value);