gpt4 book ai didi

c - C中随机数的全变体

转载 作者:行者123 更新时间:2023-12-01 12:45:44 25 4
gpt4 key购买 nike

我正在尝试使用以下代码生成 64 位随机数。我想要二进制数字,但问题是我无法让所有位都发生变化。我希望数字尽可能多地变化

void PrintDoubleAsCBytes(double d, FILE* f)
{

f = fopen("tb.txt","a");

unsigned char a[sizeof(d)];
unsigned i;
memcpy(a, &d, sizeof(d));
for (i = 0; i < sizeof(a); i++){
fprintf(f, "%0*X", (CHAR_BIT + 3) / 4, a[sizeof(d)-1-i]);

}
fprintf(f,"\n");
fclose(f); /*done!*/
}

int main (int argc, char *argv)
{

int limit = 100 ;
double a, b;
double result;
int i ;
printf("limit = %d", limit );

for (i= 0 ; i< limit;i++)
{
a= rand();
b= rand();
result = a * b;
printf ("A= %f B = %f\n",a,b);
printf ("result= %f\n",result);
PrintDoubleAsCBytes(a, stdout); puts("");
PrintDoubleAsCBytes(b, stdout); puts("");
PrintDoubleAsCBytes(result, stdout); puts("");

}
}

输出文件

41DAE2D159C00000        //Last bits remain zero, I want them to change as well as in case of the result
41C93D91E3000000
43B534EE7FAEB1C3
41D90F261A400000
41D98CD21CC00000
43C4021C95228080
41DD2C3714400000
41B9495CFF000000
43A70D6CAD0EE321

我该如何实现?我在软件编码方面没有太多经验

最佳答案

在 Java 中这很容易:

Random rng = new Random(); //do this only once

long randLong = rng.NextLong();
double randDoubleFromBits = Double.longBitsToDouble(randLong);

在 C 中,我只知道一种破解方法:)


由于 RAND_MAX 可以低至 2^15-1 但实现已定义,也许您可​​以从 rand() 中获得 64 个随机位通过掩码和移位:

//seed program once at the start
srand(time(NULL));

uint64_t a = rand()&0x7FFF;
uint64_t b = rand()&0x7FFF;
uint64_t c = rand()&0x7FFF;
uint64_t d = rand()&0x7FFF;
uint64_t e = rand()&0x7FFF;
uint64_t random = (a<<60)+(b<<45)+(c<<30)+(d<<15)+e;

然后将其填充到一个 union 体中,并使用 union 体的另一个成员将其位解释为 double .有点像

union
{
double d;
long l;
} doubleOrLong;

doubleOrLong.l = random;
double randomDouble = doubleOrLong.d;

(我没有测试过这段代码)


编辑:解释它应该如何工作

首先,srand(time(NULL));带有当前时间戳的种子 rand。因此,您只需在开始时执行一次此操作,如果您想重现早期的 RNG 系列,您可以根据需要重复使用该种子。

rand()返回一个介于 0 和 RAND_MAX 之间的随机无偏整数。 RAND_MAX 保证至少为 2^15-1,也就是 0x7FFF。为了编写程序使得 RAND_MAX 是什么无关紧要(例如,它可能是 2^16-1、2^31-1、2^32-1...),我们屏蔽了除底部以外的所有内容15 位 - 0x7FFF 是二进制形式的 0111 1111 1111 1111,或低 15 位。

现在我们必须将所有 15 个随机位打包成 64 个位。位移运算符,<< , 将左操作数(右操作数)位向左移动。所以我们称为 random 的最终 uint64_t 具有从其他变量派生的随机位,如下所示:

aaaa bbbb bbbb bbbb bbbc cccc cccc cccc ccdd dddd dddd dddd deee eeee eeee eeee

但这仍然被视为 uint64_t,而不是 double 。这样做是未定义的行为,所以你应该确保它在你选择的编译器上按照你期望的方式工作,但是如果你把这个 uint64_t 放在一个 union 中然后读取 union 的另一个双重成员,那么你会(希望!)将这些相同的位解释为由随机位组成的 double 。

关于c - C中随机数的全变体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16182630/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com