我正在使用ncurses库来构建游戏。我无法生成正确的随机数。下面的while循环需要保持生成随机数,直到它们在1到45之间(这是我在标准屏幕上的y轴限制)。我无法弄清楚我做错了什么因为while循环条件对我来说很好。问题是while循环开始无限运行。我没有做任何事情,只是在最后打印生成的数字,因为我只想看到生成正确的数字。谁有人可以帮我解决这个问题?以下是我的主要内容。
int main()
{
int r,c,x=0;
initscr();
raw();
keypad(stdscr, TRUE);
noecho();
//mvprintw(22,45,"<");
getmaxyx(stdscr,r,c);
int n,n2 = 0;
while((n<1)||(n>45)){
srand (time(NULL));
n = rand();
srand (time(NULL));
n2 = rand();
}
mvprintw(4,10,"First Random Number: %d\n", n);
mvprintw(5,10,"Second Random number: %d\n", n2);
getch();
endwin();
return 0;
}
答案 0 :(得分:3)
这是你在C ++中的方法:
#include <iostream>
#include <random>
int main()
{
std::random_device rd;
std::mt19937 gen( rd());
std::uniform_int_distribution<> dis( 1, 45);
for (int n=0; n<1000; ++n)
std::cout << dis(gen) << ' ';
std::cout << '\n';
}
使用rand() % x
是一个有缺陷的设计,因为引入的偏差是不均匀地划分范围。您可以阅读this,详细了解rand() % x
引入的偏见。
答案 1 :(得分:2)
您希望在事情开始时调用srand
一次,然后使用模数将rand
结果带入您的范围,例如:
srand(time(NULL));
n = rand() % 45 + 1;
n2 = rand() % 45 + 1;
答案 2 :(得分:1)
就像@unholySheep评论的那样,rand()返回一个介于0和RAND_MAX之间的值,这是一个巨大的值。因此,您很可能不会快速获得1到RAND_MAX之间的值。
因此,解决方案是按照您想要的数字提醒除法:
n = 1 + rand() % 45;
你甚至不需要一段时间。
答案 3 :(得分:1)
您可以获得1到45之间的随机数:
n = rand() % 45 + 1;
它在分发方面不会很完美,但它对于既不是统计学家也不是密码学家的人来说足够接近,在这种情况下你可能会使用 real 随机数。
您还应该在程序开始时的某个地方拨打srand()
一次,而不是多次,特别是如果您正在使用当前时间播种它。
在同一秒内多次执行此操作将为您提供明确的非随机序列,例如:
42, 42, 42, 42, 42, 42, 42, ...