Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/162.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ RAND_MAX和UINT_MAX之间的差异会有所不同吗?_C++_Random_Bit Manipulation - Fatal编程技术网

C++ RAND_MAX和UINT_MAX之间的差异会有所不同吗?

C++ RAND_MAX和UINT_MAX之间的差异会有所不同吗?,c++,random,bit-manipulation,C++,Random,Bit Manipulation,我的家庭作业是在0和2^30之间做随机整数。现在,在过去我们了解到,rand()只返回小于rand\u MAX的整数,这小于UINT\u MAX,我们可以使用位移位来填充UINT\u MAX容量。从我所做的一些阅读(这里,等等),我意识到如果这些数字的分布对我来说很重要,这可能不是一个很好的主意。话虽如此,我的教授已经详细说明了这种方法 我的问题是,通过多少位移位?RAND_MAX和UINT_MAX之间的差异是否总是存在一个安全常数来进行位移位?或者,是否需要进行一些初始探测来确定要移位的位数?

我的家庭作业是在
0
2^30
之间做随机整数。现在,在过去我们了解到,
rand()
只返回小于
rand\u MAX
的整数,这小于
UINT\u MAX
,我们可以使用位移位来填充
UINT\u MAX
容量。从我所做的一些阅读(这里,等等),我意识到如果这些数字的分布对我来说很重要,这可能不是一个很好的主意。话虽如此,我的教授已经详细说明了这种方法

我的问题是,通过多少位移位?
RAND_MAX
UINT_MAX
之间的差异是否总是存在一个安全常数来进行位移位?或者,是否需要进行一些初始探测来确定要移位的位数?我是否应该保持位移动一点点,然后对照
UINT\u MAX

我问的原因是,
UINT_MAX
被定义为至少是一个特定的数字(
65535
),但在我的机器上,
UINT_MAX
要大得多(
4294967295
)。这让我担心,我可能会在周末完成作业,到达学校,发现一切都不够好,无法提交

谢谢

参考文献:

我读过几个类似的问题,但都没有得到答案

事实上,上面的第二个问题让我怀疑这样做的价值

事实上,上面的第二个问题让我怀疑这样做的价值

如果你的教授让你这样做,你应该这样做。这当然不是加密强度,但对于家庭作业来说,这是可以的

对于
RAND_MAX
2^n-1
,我通常会这样假设。计算机生成随机数的方式是一次生成一组位,因此,如果最大值不是
2^n-1
,则不是该范围内的所有数字都可以返回,就是熵会被浪费

至于所有系统的差异都是相同的,我强烈建议不要这样假设。在您的代码中,计算出每个位中有多少位,并动态地计算出如何移位


你不能用ssh连接到你最终要运行的学校服务器吗

您的问题集中在
RAND_MAX
UINT_MAX
之间是否有一点偏移。这就引出了
UINT_MAX
RAND_MAX
是否为
2^k-1
形式的问题
UINT_MAX
几乎可以肯定会出现在任何基于二进制数系统的计算机上。如果<代码> SIEZOF(int)=32 位,则<代码> k=32 < /代码>,如果<代码> siZeof(int)=64位< /代码>,则<代码> k=64 < /代码>等。现在我们可以移动考虑<代码> RANDMAX 。在大多数实现中,答案是
RAND_MAX
几乎总是
2^k-1
的形式。为什么?我们需要考虑<代码> RAND()/<代码>的大部分实现方式如何工作。

  • rand()
    通常使用线性同余生成器(参见或Knuth“计算机程序员的艺术第2部分:半数值算法”)。基本上,随机数是一个带有
    种子的序列

    x(k+1)=(ax(k)+c)%m

  • (即C库存储最后一次迭代的
    x(k)
    ,当您调用
    rand()
    时,它返回
    x(k+1)

  • 要获得良好的质量,必须仔细选择发电机的参数(
    a
    c
    、和
    m
    )。质量通常包括序列自身重复的次数等。选择这些参数时的一个紧张因素是使
    m
    尽可能接近
    UINT_MAX
    ,以避免浪费潜在的随机位。如果研究生成器,通常正确的选择是使
    m
    稍微小于
    UINT\u MAX
    。您还需要将
    m
    设为素数


  • 通常,您希望
    rand()
    的速度尽可能快,因此您希望这些操作便宜。最便宜的
    mod
    计算是
    foo%(2^k-1)
    的一种形式,因为它可以实现为
    foo&(1出于好奇,你上哪所学校?加拿大不列颠哥伦比亚省温哥华的兰加拉学院):)嗯,
    rand
    永远不会是加密安全的。哇。我想一个星期后你就会名声大噪。这正好回答了我所有的担忧,如果我能投票100次,我可能会。非常感谢。还有:很棒的简历!constexpr bool是2减去1(无符号长n){return(n&(n+1))==0;}的幂吗
    unsigned int myrand()
    {
            static_assert(sizeof(int)==4,"sizeof(unsigned int) != 4");
            static_assert(is_power_of_two_minus_one(RAND_MAX),"RAND_MAX not a power of two minus one");
            static_assert(is_power_of_two_minus_one(UINT_MAX),"UINT_MAX not power of two minus one");
            unsigned int raw_rand=rand();
            // do your bit shift to adjust raw_rand
            return raw_rand;
    }