C#中使用位掩码正确判断并清除ushort前两位的方法
问题根因
原代码的判断逻辑存在错误:
ushort是16位无符号整数,位序号从0开始计数,需要检查的最高两位对应第15位、第14位。1 << 15的计算结果是32768(二进制1000000000000000),1 << 14的结果是16384(二进制0100000000000000)。- 原代码将按位与的结果直接和
1比较,只有结果等于十进制1时判断才成立,但这两个位置1时,按位与得到的是32768、16384,永远不可能等于1,所以if分支永远不会触发。
正确实现
不需要逐位单独判断,使用组合掩码可以简化逻辑:
- 构造覆盖最高两位的组合掩码:
(1 << 15) | (1 << 14),对应值为0xC000(二进制1100000000000000) - 判断时,将元素和该掩码做按位与运算,若结果等于掩码本身,说明最高两位均为1
- 清除位时,将元素和掩码的按位取反结果做与运算,一次即可清除两位,无需分两次操作
修正后代码:
static public void trimData(ushort[] rawData) { const ushort topTwoBitsMask = (1 << 15) | (1 << 14); for(int i = 0; i < rawData.Length; i++) { if ((rawData[i] & topTwoBitsMask) == topTwoBitsMask) { rawData[i] = (ushort)(rawData[i] & ~topTwoBitsMask); } } }
如果一定要逐位判断,正确的写法是判断按位与结果是否非0,而非等于1,这种写法冗余不推荐:
if( ((rawData[i] & (1 << 15)) != 0) && ((rawData[i] & (1 << 14)) != 0) ) { // 清除逻辑 }
内容的提问来源于stack exchange,提问作者29belgrade29
相关产品推荐
相关产品推荐

