首页 > 解决方案 > 每 (n) 秒打印一次的程序

问题描述

我编写了一个程序,每五秒会在十秒的时间范围内打印一个随机数(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;

标签: c++clock

解决方案


编辑:我觉得这个答案不完整,因为它没有回答你的实际问题。第一部分现在解释了您的方法失败的原因,第二部分是关于如何以更好的方式解决您的问题。

您正在clock()以某种方式使用,您等待多个特定时间点。由于 的性质clock()和有限的精度float,您的检查基本上相当于说:我们在一个窗口[x-eps, x+eps]中,其中x是 的倍数,5通常eps很小,取决于使用的浮点类型和大小(clock() - start)。增加的一种方法eps是添加一个常量 like 1e6to (clock() - start)。如果浮点数是精确的,那不应该影响你的逻辑,因为1e6它是 的倍数5,但实际上它会非常严重。

在一台快速机器上,该条件可以每 5 秒多次为真;在一台慢速机器上,每次 5 秒过去时,它可能都不是真的。

实现它的正确方法如下;但是,如果您想使用轮询方法(就像您目前所做的那样)来执行此操作,则必须在您的 -block 中将 start 增加 5 * CLOCKS_PER_SECONDif并将条件更改为类似(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.

推荐阅读