C 用mod计算兰德的动态范围

C 用mod计算兰德的动态范围,c,random,64-bit,bit-manipulation,C,Random,64 Bit,Bit Manipulation,我想创建一个介于1和bit_cnt的动态值之间的rand范围 在阅读了关于rand函数的更多内容后,我了解到现成的rand的范围是[0,rand_MAX]。我还了解RAND_MAX的值取决于库,但保证至少为32767 我必须创建一个64 0的位掩码 现在,我尝试将位掩码左移一个动态值bit_cnt,并随机生成一个介于1和bit_cnt动态值之间的位数 例如,当bit_cnt为10时,我想随机化最低的10位 原来我有 mask = (mask << bit_cnt) + (rand()

我想创建一个介于1和bit_cnt的动态值之间的rand范围

在阅读了关于rand函数的更多内容后,我了解到现成的rand的范围是[0,rand_MAX]。我还了解RAND_MAX的值取决于库,但保证至少为32767

我必须创建一个64 0的位掩码

现在,我尝试将位掩码左移一个动态值bit_cnt,并随机生成一个介于1和bit_cnt动态值之间的位数

例如,当bit_cnt为10时,我想随机化最低的10位

原来我有

mask = (mask << bit_cnt) + (rand()% bit_cnt);
,但仍发生浮点异常

然后我尝试了以下想法,认为该值不是0,因此将该值至少增加到1:

mask = (mask << bit_cnt) + ((rand()% bit_cnt)+1);
浮点异常的原因是什么?这就是动态创建rand函数范围的方法吗

我感谢你的建议。多谢各位

更新: 我将if语句更改为以下内容:

mask = (mask << bit_cnt) + (1+(rand()%(bit_cnt+1)));
if(bit_cnt !=0) 
然后执行其余的逻辑

我收到了以下输出:

0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000010
0000000000000000000000000000000000000000000000000000000000000100
0000000000000000000000000000000000000000000000000000000000001000
0000000000000000000000000000000000000000000000000000000000010010
0000000000000000000000000000000000000000000000000000000000100001
0000000000000000000000000000000000000000000000000000000001000100
0000000000000000000000000000000000000000000000000000000010000110
0000000000000000000000000000000000000000000000000000000100000011
0000000000000000000000000000000000000000000000000000001000000000
0000000000000000000000000000000000000000000000000000010000001000
0000000000000000000000000000000000000000000000000000100000000111
0000000000000000000000000000000000000000000000000001000000000110
0000000000000000000000000000000000000000000000000010000000000110
0000000000000000000000000000000000000000000000000100000000001100
0000000000000000000000000000000000000000000000001000000000000010
0000000000000000000000000000000000000000000000010000000000001101
0000000000000000000000000000000000000000000000100000000000000110
0000000000000000000000000000000000000000000001000000000000010000
0000000000000000000000000000000000000000000010000000000000000100
有没有办法知道范围是否正确?比如,通过查看输出是否有可能知道

const int LINE_CNT = 20;
void print_bin(uint64_t num, unsigned int bit_cnt);
uint64_t rand_bits(unsigned int bit_cnt);

int main(int argc, char *argv[]) {

    int i;

    srand(time(NULL));
    for(i = 0; i < LINE_CNT; i++) {
        uint64_t val64 = rand_bits(i);
        print_bin(val64, 64);
    }

    return EXIT_SUCCESS;
}
void print_bin(uint64_t num, unsigned int bit_cnt) {

    int top_bit_cnt;

    if(bit_cnt <= 0) return;
    if(bit_cnt > 64) bit_cnt = 64;

    top_bit_cnt = 64;
    while(top_bit_cnt > bit_cnt) {
        top_bit_cnt--;
        printf(" ");
    }

    while(bit_cnt > 0) {
        bit_cnt--;
        printf("%d", (num & ((uint64_t)1 << bit_cnt)) != 0);
    }
    printf("\n");

    return;
}
uint64_t rand_bits(unsigned int bit_cnt) {
    uintmax_t mask = 1;
    if (bit_cnt != 0) {
        mask = (mask << bit_cnt) + (rand()% bit_cnt);
    }
    return mask;
}
问题是,如果位为0,则任何%bit\u cnt都将得到错误。在尝试执行模数之前,需要检查位

if (bit_cnt != 0) {
    mask = (mask << bit_cnt) + (rand()% bit_cnt) + 1;
}

您所有的尝试都执行了模数运算,然后尝试对结果进行处理,但这是在错误发生之后进行的。

这将使用位计数生成掩码。如果希望比特数大于RAND_MAX所能填充的比特数,请实现另一个随机函数,如我前面所评论的

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void) {

    int bit_cnt = 10;
    unsigned mask = 0;
    int i;
    int num;
    srand((unsigned)time(NULL));

    for(i = 0; i < bit_cnt; i++)
        mask = (mask << 1) | 1;

    printf ("For bit_cnt=%d, mask=0x%X\n\n", bit_cnt, mask);

    for (i = 0; i < 5; i++) {
        num = rand() & mask;
        printf("Random number 0x%0*X\n", 1+(bit_cnt-1)/4, num);
    }
}

我看不出输出与这个问题有什么关系。这些数字来自哪里?是什么决定了您显示的是32位还是64位?位的值来自哪里?另外,请忽略我输出的与32位值相关的内容,因为我只关注64位值。我只保留了与64位值相关的代码。最近,虽然被评论为不可移植,但您可以适应64位int。浮点与这个问题有什么关系?和由于问题更新,如果只有最低位是随机的,那么64位的相关性是什么?如果你只想随机选择最低的位,用1,3,7,15等来屏蔽rand。@WeatherVane我查看了另一个问题中的代码。在您的代码中,您能解释一下17、2和3的值来自哪里吗?非常感谢。另外,我遇到了一个浮点异常,因为rand上的mod函数变成了0。使用update时,值1、3、7和15从何而来?它们将15位结果与32位变量对齐。移位17用于ms 15位,移位2用于接下来的ls 15位,留下2位,因此&3是最小的两位,二进制11I不理解这个问题。你说你想要一个介于1和位之间的随机数。所以当bit_cnt为10时,您将得到从1到10的值。你的意思是你真的想把所有10个低阶位随机化吗?这根本不是一回事。
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000001
0000000000000000000000000000000000000000000000000000000000000000
0000000000000000000000000000000000000000000000000000000000000010
0000000000000000000000000000000000000000000000000000000000001000
0000000000000000000000000000000000000000000000000000000000001001
0000000000000000000000000000000000000000000000000000000000000010
0000000000000000000000000000000000000000000000000000000000010101
0000000000000000000000000000000000000000000000000000000001001111
0000000000000000000000000000000000000000000000000000000010000011
0000000000000000000000000000000000000000000000000000001010101001
0000000000000000000000000000000000000000000000000000010101101100
0000000000000000000000000000000000000000000000000000101011111000
0000000000000000000000000000000000000000000000000001001010101111
0000000000000000000000000000000000000000000000000011101011000101
0000000000000000000000000000000000000000000000000001001101111101
0000000000000000000000000000000000000000000000001111000000111010
0000000000000000000000000000000000000000000000000101100000001100
0000000000000000000000000000000000000000000000100111101000111111
0000000000000000000000000000000000000000000001010101011101000110



uint64_t rand_bits(unsigned int bit_cnt) {
            uintmax_t mask = 1;
    if (bit_cnt != 0) {
    mask = rand() % (1 << bit_cnt);
    }
    return mask;
    }
if (bit_cnt != 0) {
    mask = (mask << bit_cnt) + (rand()% bit_cnt) + 1;
}
#include <stdio.h>
#include <stdlib.h>
#include <time.h>

int main(void) {

    int bit_cnt = 10;
    unsigned mask = 0;
    int i;
    int num;
    srand((unsigned)time(NULL));

    for(i = 0; i < bit_cnt; i++)
        mask = (mask << 1) | 1;

    printf ("For bit_cnt=%d, mask=0x%X\n\n", bit_cnt, mask);

    for (i = 0; i < 5; i++) {
        num = rand() & mask;
        printf("Random number 0x%0*X\n", 1+(bit_cnt-1)/4, num);
    }
}
For bit_cnt=10, mask=0x3FF

Random number 0x327
Random number 0x39C
Random number 0x1B1
Random number 0x088
Random number 0x26E