为特定的半字节创建掩码
问题描述:
如何以尽可能高效的方式为所有半字节创建一个无符号64位整数的掩码,以匹配某个值?为特定的半字节创建掩码
例如,假设我有一个64位无符号整数:
0000 0100 0011 0011 0011 0011 0010 0010 0010 0010 0010 0010 0001 0001 0001 0001
而且说我只希望允许拥有的0010 值啃我怎样才能找到那些蚕食和创建蒙为他们。 在这种人为的例子我知道当然半字节5:10是0010,等等对应的掩模来创建是:
0000 0000 0000 0000 0000 0000 1111 1111 1111 1111 1111 1111 0000 0000 0000 0000
但是我想为任何64位无符号整数,任何形成这种掩模蚕食价值。例如,我可能对0100
,0010
或1000
半字节感兴趣。
答
例如如下(只是的公知的技巧的组合物)
- XOR与期望的值,使得一个半字节0 当且仅当它具有正确的值
- 计算水平-OR为所有啃
- 删除垃圾位
- 加宽的结果,以适应整个啃
- 面具最终倒,反转回来
所以没有测试:
x ^= test_value
// now h-OR nibbles
x |= x >> 1
x |= x >> 2
// remove junk
x &= 0x1111111111111111
// widen
x *= 15
// invert
x = ~x
+0
真是太神奇了,谢谢!我在回答问题之前10分钟就想出了一个解决方案,我已经将它包括在内以提供完整性,但它不像您的解决方案那么简洁!我接受你的答案。 – Ward9250
答
这里有一个版本,我设法拿出试验和错误小时后,却是近norwhere以纯如哈罗德的版本。为了完整性,我在这里发布它: 我把它写在茱莉亚语言中。
@inline function mask_nibbles(x::UInt64, value::UInt64)
x = ~(x $ value)
x = (x & 0x1111111111111111) &
((x >> 1) & 0x1111111111111111) &
((x >> 2) & 0x1111111111111111) &
((x >> 3) & 0x1111111111111111)
return x | (x << 1) | (x << 2) | (x << 3)
end
这是一个解谜意义上的有趣问题,但我不知道它是否可能是XY问题? – njuffa