我编写了一个程序,该程序每五秒钟将在十秒钟的时间范围内打印一个随机数(1-10)。但是似乎每五秒钟打印一个以上的随机数。有人能指出我正确的方向吗?
clock_t start;
int random;
start = clock();
while (float(clock() - start) / CLOCKS_PER_SEC <= 10.0) {
if (fmod(float(clock() - start) / CLOCKS_PER_SEC, 5) == 0 && (float(clock() - start) / CLOCKS_PER_SEC) != 0) {
random = rand() % 10 + 1;
cout << random << endl;
}
}
return 0;
答案 0 :(得分:6)
编辑:我认为此答案不完整,因为它不能回答您的实际问题。现在,第一部分说明了您的方法失败的原因,第二部分是如何更好地解决问题的方法。
您正在以某种方式使用clock()
,在这种情况下您要等待许多特定的时间点。由于clock()
的性质和float
的有限精度,您的检查基本上等于说:我们在窗口[x-eps, x+eps]
中,其中x
是...的倍数。 5
和eps
通常很小,并且取决于所使用的浮点类型以及(clock() - start)
的大小。增加eps
的一种方法是向1e6
添加一个类似(clock() - start)
的常量。如果浮点数是精确的,那不会影响您的逻辑,因为1e6
是5
的倍数,但实际上它将如此。
在快速的机器上,该条件可以每5秒多次出现。在速度较慢的计算机上,每过5秒钟可能就不是真的。
实现它的正确方法如下:但是,如果您想使用轮询方法来进行此操作(就像您当前所做的那样),则必须在if
块中以5 * CLOCKS_PER_SECOND开始,并将条件更改为(clock() - start) / CLOCKS_PER_SECOND >= 5
。
除了您遇到的clock()
特有的问题外,我想提醒您,它可以测量CPU时间或滴答滴答,并且不是测量时间的可靠方法。幸运的是,在现代C ++中,我们有std::chrono
:
auto t = std::chrono::steady_clock::now();
auto end = t + std::chrono::seconds( 10 );
while( t < end )
{
t += std::chrono::seconds( 5 );
std::this_thread::sleep_until( t );
std::cout << ( rand() % 10 + 1 ) << std::endl;
}
我还强烈建议用rand()
中更现代的工具替换<random>
,例如:
std::random_device rd; // Hopefully a good source of entropy; used for seeding.
std::default_random_engine gen( rd() ); // Faster pseudo-random source.
std::uniform_int_distribution<> dist( 1, 10 ); // Specify the kind of random stuff that you want.
int random = dist( gen ); // equivalent to rand() % 10 + 1.
答案 1 :(得分:5)
您的代码似乎足够快并且您的计算精度足够小,因此您可以在计算数量更改之前进行多次迭代。因此,当条件匹配时,它将一次匹配几次。
但是,这不是一个好方法,因为您正在使计算机非常努力地工作。这种等待方式将给一个处理器带来相当大的负担,有可能减慢您的计算机速度,并肯定会消耗更多功率。如果您使用的是四核台式机,那还不错,但是对于笔记本电脑而言,电池却实在是难上加难。而不是问您的计算机“是时候了吗?是时候了吗?是时候了吗?”尽可能快地相信计算机知道如何等待,并使用sleep
,usleep
,sleep_for
或您正在使用的任何库调用它。有关示例,请参见here。