有没有办法根据位位置选择一个值。问题陈述是: - 对于16位的位置,我可以设置任何位,比如我设置1,4,6,7,11,13位 所以面具将是: -
Bit Positons 0 0 1 0 1 0 0 0 1 1 0 1 0 0 1 0
现在我需要根据这个位掩码随机选择一个值,其中只设置了1位,所以我可能的值可能是: -
用于选择4:0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
For Selecting 7: 0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0
但是我需要随机选择这个值,所以我喜欢这样做
1)根据位掩码创建一个数组,因此对于16位,数组将有16个唯一值。
2)现在对数组位置执行rand操作以获取数组索引。
3)使用该数组索引处的值。
有更好的方法吗?
答案 0 :(得分:3)
如果我理解正确,你想要一个只有一个位设置的数字也在掩码中设置。
要做到这一点,我会做一个while循环,选择0到16之间的随机值,直到找到一个也在掩码中设置的值:
uint16_t mask = 0x28d2; /* == 0 0 1 0 1 0 0 0 1 1 0 1 0 0 1 0 */
int bit = 0;
do{
bit = 1 << (rand() % 16); /* sets one random bit between 1 and 16 */
}while(!(mask & bit));
/* bit has now exactly one bit set that is also set in mask */
答案 1 :(得分:1)
如果目标是在最后设置一个最多一位的值,则不需要该数组。你可以简单地随机生成一个介于0-15之间的值,然后将该值留下的位移1,以获得用于选择该位的掩码,如下所示:
uint16_t myValue = 0xA5;
int shiftValue = rand() % 16;
uint16_t randomMask = 1u << shiftValue;
uint16_t randomValue = myValue & randomMask;
如果你需要一个只有一个最后设置的位的值,它会变得有点棘手。此时,您可以执行或多或少的操作,并使用数组来存储所设置位的位置(例如[1, 4, 6, 7, 11, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
,使用零来指示何时不再设置位),然后生成包含有效索引的数组部分的随机索引。当然还有其他方法可以做到这一点,但这种方式似乎对未来的代码读者来说相当清楚(尽管我仍然会仔细评论这一点,因为位操作可能会让人感到困惑)。
(顺便说一句,有更好的方法来生成随机数而不是rand()
,如果你需要任何接近真正随机性的东西,你应该使用其中一种 - 我只是在这里使用它作为方便的简写,因为实际的RNG并不重要。)
答案 2 :(得分:0)
你可以这样做:
bitMask = 0x28d2;
randomNum = rand() % 16;
randomBit = (1<<randomNum) & bitMask;
答案 3 :(得分:0)
如果你想要完全一位设置,你可以使用一个重试循环,或类似的东西:(添加适当的定义,并可能为mask == 0
添加一个特殊情况)
while (mask)
{
array[i++] = mask & -mask;
mask &= mask - 1;
}
return array[rand_in_range(0, i)];
其中rand_in_range(a, b)
是一个返回范围[a,b>的范围内的随机数的函数。 (请注意,rand_in_range
的99%的实现都是错误的,而在大多数测试中看起来都是正确的,这是最糟糕的错误。)