【发布时间】:2011-10-27 14:47:00
【问题描述】:
我很难理解为什么这段代码(尝试在 C++11 中使用新的 <random> 标头)在 [0, 2**62 - 1] 中正确生成随机数,而不是在 [0, 2**63 - 1] 或 [0, 2**64 - 1] 中生成随机数。
#include <iostream>
#include <stdint.h>
#include <random>
#include <functional>
#include <ctime>
static std::mt19937 engine; // Mersenne twister MT19937
void print_n_random_bits (unsigned int n);
int main (void) {
engine.seed(time(0));
print_n_random_bits(64);
print_n_random_bits(63);
print_n_random_bits(62);
return 0;
}
void print_n_random_bits (unsigned int n)
{
uintmax_t max;
if (n == 8 * sizeof(uintmax_t)) {
max = 0;
} else {
max = 1;
max <<= n;
}
--max;
std::uniform_int_distribution<uintmax_t> distribution(0, max);
std::cout << n << " bits, max: " << max << std::endl;
std::cout << distribution(engine) << std::endl;
}
现在,进一步挖掘发现 std::mt19937_64,它具有正确的行为,但谁能向我解释为什么适用于 62 位数字的东西不适用于 64 位数字?
编辑:抱歉,我什至没有具体说明问题所在。 问题在于,对于 63 位和 64 位最大值,输出始终是 [0, 2**32 - 1] 范围内的数字,例如:
% ./rand
64 bits, max: 18446744073709551615
1803260654
63 bits, max: 9223372036854775807
3178301365
62 bits, max: 4611686018427387903
2943926730538475327
% ./rand
64 bits, max: 18446744073709551615
1525658116
63 bits, max: 9223372036854775807
2093351390
62 bits, max: 4611686018427387903
1513326512211312260
% ./rand
64 bits, max: 18446744073709551615
884934896
63 bits, max: 9223372036854775807
683284805
62 bits, max: 4611686018427387903
2333288494897435595
编辑 2:我正在使用 clang++ (Apple clang version 2.1 (tags/Apple/clang-163.7.1)) 和“libc++”。由于我的版本不支持c++0x,因此我无法使用 GCC 轻松测试上述内容。
【问题讨论】:
-
它到底在做什么出乎意料?也就是说,它究竟如何为您提供与您的预期不同的结果?
-
另外,您使用的是什么标准库实现?
-
认为这可能只是运气不好:)
-
使用 GCC4.5.1,所有三个测试(62/63/64 位)都返回 32 位值。 ideone.com/3GZ9S
-
使用 GCC4.6.1,所有三个测试(62/63/64 位)都返回 64 位值。