如何根据位的位置随机选择一个值

时间:2013-10-07 23:40:46

标签: c arrays random bit-manipulation bitwise-operators

有没有办法根据位位置选择一个值。问题陈述是: - 对于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)使用该数组索引处的值。

有更好的方法吗?

4 个答案:

答案 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%的实现都是错误的,而在大多数测试中看起来都是正确的,这是最糟糕的错误。)