unsigned long ulrand(){
return (
(((unsigned long)rand()<<24)& 0xFF000000ul)
|(((unsigned long)rand()<<12)& 0x00FFF000ul)
|(((unsigned long)rand())& 0x00000FFFul)
);
}
unsigned long 通常是32位或64位的无符号整型,具体取决于环境,可以通过如下代码查看当前环境的unsigned long的位数
#include <stdio.h>
#include <limits.h>
int main() {
printf("unsigned long is %llu bits\n", sizeof(unsigned long) * CHAR_BIT);
//sizeof() get the bytes of unsigned long
//char_bit 1 byte = 8 bits .So char_bit = 8
return 0;
}
我在win11 64位系统上得到的结果是32位
当需要获得32位的无符号整型时,如果使用rand(),rand()生成结果的范围是0-32768,其中,32768为2的15次方-1,即二进制:111111111111111(总共15个1),也就是15位,不够我们需要的32位,15*3=45>32
因此,我们的思路是生成3次15位的随机数,把三个数拼成一个32位的随机数
具体实现:将32位拆成 25-32位 13-24位 1-12位三个部分
先生成一个15位的随机数,然后将其 << 24 ,即左移24位,那么原来的第 1-15 位,现在变为第 25-39 位,39位超过了需要的32位,此时,只要保留 25-32 位即可,共8位,那么我们将其与 二进制:1111 1111 0000 0000 0000 0000 0000 0000 进行 与 操作,就得到了第25-32位,此二进制数用16进制表示为:0xFF000000,同样的,现在需要第13-24位,左移12位后,得到了第 13-27位,只需要13-24位,所以将其与 1111 1111 1111 0000 0000 0000 进行 与 ,此用16进制表示为 0xFFF000,将其补位32位,即是 0x00FFF000(补0不必要,见后文 “注”),最后,需要第1-12位,此时不需要移位操作,直接取1-12位即可,方法同上,与 二进制:1111 1111 1111,即16进制:0xFFF进行 与 操作即可,(同样地,补0后,变为0x00000FFF,不必要)
最后将三个部位进行 或 操作,合为一个32位的二进制数,即一个unsigned long long类型的数
注
大家可以通过实验,看下 unsigned long long的强制类型转换 以及 16进制数结尾的 ul (unsigned long)类型表示,能不能去掉。我实验后结果表明,可以去掉,即代码如下
unsigned long ulrand(){
return (
((rand()<<24)& 0xFF000000)
|((rand()<<12)& 0xFFF000)
|((rand())& 0xFFF)
);
}
3812

被折叠的 条评论
为什么被折叠?



