在处理字符串和短裤时应用位掩码的更快方法
本文关键字:掩码 方法 应用 字符串 处理 | 更新日期: 2023-09-27 18:34:20
我有以下代码,它将接受一串单词和一个位掩码。它将掩码应用于某个单词的某个块(由 startWord、highBit 和 length 指定(,如果掩码匹配,则返回 true 或 false 值。
它有效,但不是很快。肯定有办法做得更好吗?
编辑:
为了澄清,highBit和length用于缩短单词的长度。因此,如果我们有一个单词是 dec:37,那么二进制是 0b100101。如果它的位很高 2,长度为 2,那么我们只关心将掩码应用于最后两位数字 (01(。如果它的位高位为 3,长度为 2,那么它将是方括号中的数字:0b100[10]1 等。
它有效地检查在掩码中设置的任何位是否也在相应位置的相应单词中设置。
进一步编辑:
如果我们有单词 37 (0b100101( 和掩码 (0b1(,并且我们对整个单词感兴趣(所以高位是 15,长度是 16(,那么这将评估为 true。如果掩码为 0b0,那么它也将评估为 true(我们只是在寻找设置的位(。
掩码的长度应始终大于所分析单词部分的"长度"。
public bool AddMask(string maintMessage, short mask, int startWord, int highBit, int length)
{
// Maintenance message is a string of decimal 16-bit values
// seperated by semi-colons.
var splitMsg = maintMessage.Split(';');
var word = splitMsg[startWord];
return AddMask(short.Parse(word), mask, highBit, length);
}
public bool AddMask(short wordToMask, short mask, int highBit, int length)
{
if (highBit < length)
length = highBit; // Or throw an exception?
var binWord = Convert.ToString(wordToMask, 2);
if (length > binWord.Length) // Shorten 'length' to max possible length
length = binWord.Length;
binWord = binWord.Substring(binWord.Length - highBit, length);
var shortWord = Convert.ToInt16(binWord, 2);
var result = shortWord & mask;
return result == mask;
}
理解正确,您真正想说的是该方法应返回true
当且仅当wordToMask
值中的每个位都设置在相应位置时,在mask
中设置相同的位,并限定mask
值应与要检查的位组对齐。
如果是这样,那么您的问题归结为这样简单的事情:
bool AddMask(short wordToMask, short mask, int highBit, int length)
{
return mask == ((wordToMask >> (highBit - length)) & mask);
}
换句话说,将原始数据向右移动,以便要检查的位从 0 开始 - 即与mask
对齐 - 然后执行逐位&
,查看结果是否与mask
相同。如果mask
中的任何位未在wordToMask
中设置,它们将被设置为 0,并且结果将不匹配。否则,它会。
我应该指出,从 1 开始对位进行编号有点不寻常。与数组一样,位通常从 0 开始索引。但以上内容符合您的描述;例如,如果highBit
是2,length
是2,你说你只想考虑两个最低位。
上面还假设mask
不会在无关紧要的地方设置位。如果不是这种情况,那么您将不得不添加更多代码来掩盖您想要忽略的更高位。那看起来更像这样:
bool AddMask(short wordToMask, short mask, int highBit, int length)
{
// Shift the word to align with the mask
short result = (short)(wordToMask >> (highBit - length)),
resultMask = (short)((1 << highBit) - 1);
// Clear all the bits higher than highBit
result &= resultMask;
// Compare with the mask
return (resultMask & mask) == (result & mask);
}