nbo*_*eel 5 c++ random bit-manipulation
我生成了许多随机数,在C ++中需要在1到15(包括)之间。当然,我可以生成的zillons,
std::uniform_int_distribution<std::mt19937::result_type> random(1, 15);
但这是浪费的,因为此mersenn扭曲器生成32位(或使用mt19937_64甚至生成64位)随机值,而我只保留4位并丢弃所有其余值,就我而言,性能是一个问题,随机数的产生是重要的因素。
因此,我的想法是生成例如0到2 ^ 64-1之间的单个64位随机值,并从中选择4位。问题是我找不到在1到15之间生成值的方法。示例:
unsigned long long int r = uniform(generator); // between 0 and 2^64-1
unsigned int r1 = (r+1)&15; // first desired random value
unsigned int r2 = ((r>>4)+1)&15; //second desired random value
unsigned int r3 = ((r>>8)+1)&15; //third desired random value
...
Run Code Online (Sandbox Code Playgroud)
在这里,这个版本当然不起作用:尽管为+1,但生成的值仍在0到15之间(因为如果r&15碰巧0xb1111加上1会产生结果0xb0000)。
另外,我希望分布保持一致(例如,我不希望偏向最低有效位的出现频率更高,(r&15+1)|((r&15 +1) >> 4)因为值0xb0001会经常出现两次,所以可能是这种情况。
代替
std::mt19937 gen(seed);
std::uniform_int_distribution<> dis(1, 15);
auto r1 = dis(gen);
auto r2 = dis(gen);
auto r3 = dis(gen);
auto r4 = dis(gen);
Run Code Online (Sandbox Code Playgroud)
你可能会这样做:
std::mt19937 gen(seed);
std::uniform_int_distribution<> dis(0, 15 * 15 * 15 * 15 - 1); // Assuming int at least 16 bits
auto r = dis(gen);
auto r1 = r % 15 + 1; r /= 15;
auto r2 = r % 15 + 1; r /= 15;
auto r3 = r % 15 + 1; r /= 15;
auto r4 = r + 1;
Run Code Online (Sandbox Code Playgroud)
快速基准测试(第二个版本比第一个版本快 2.5 倍)
| 归档时间: |
|
| 查看次数: |
132 次 |
| 最近记录: |