【发布时间】:2018-12-10 10:06:24
【问题描述】:
我正在使用clock() 函数测试基于ctime 库的计时器。 请注意,以下代码仅用于测试目的。
#include <ctime>
unsigned long Elapsed(void);
clock_t start = 0;
clock_t stop = 0;
int main()
{
start = std::clock();
while(1)
{
sleep(1);
cout << "Elapsed seconds: " << Elapsed() << endl;
}
return 0;
}
unsigned long Elapsed()
{
stop = std::clock();
clock_t ticks = stop - start;
double seconds = (double)ticks / CLOCKS_PER_SEC; //CLOCK_PER_SEC = 1 milion
return seconds;
}
如您所见,当 Elapsed() 返回计算值时,我正在执行从 double 到 unsigned long 的隐式转换。 32 位系统的无符号长限制为 2,147,483,647,并且在 Elapsed() 返回 2146 后出现溢出。
看起来该函数将“ticks”转换为 unsigned long,CLOCK_PER_SEC 转换为 unsigned long,然后返回值。当它转换“刻度”时,它会溢出。
相反,我希望它首先计算 "ticks"/CLOCK_PER_SEC 的 double 值,然后将其转换为 unsigned long。
为了计算更多秒数,我尝试返回一个 unsigned long long 数据类型,但变量总是以相同的值 (2147) 溢出。
您能否解释一下为什么编译器会转换为 unsigned long long “先验”以及为什么即使使用 unsigned long long 它也会以相同的值溢出? 有没有什么方法可以更好地编写 Elapsed() 函数来防止溢出发生?
【问题讨论】:
-
unsigned long对于 32 位系统的限制是4294967295,它是std::clock(),每 2147 秒循环一次:en.cppreference.com/w/cpp/chrono/c/clock 所以seconds是一个介于0和2147,所以隐式转换为unsigned long就可以了。 -
@M.M 已编辑,抱歉。
标签: c++ integer-overflow ctime