c++ - 隐式转换 double 到 unsigned long 溢出 c++

标签 c++ integer-overflow ctime

我正在使用 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 的双倍值,然后将其转换为 unsigned long。

在尝试计算更多秒数时,我试图返回一个 unsigned long long 数据类型,但变量总是在相同的值 (2147) 处溢出。

你能解释一下为什么编译器转换为 unsigned long long “a priori” 以及为什么即使使用 unsigned long long 它也会溢出相同的值吗? 有什么方法可以更好地编写 Elapsed() 函数来防止发生溢出?

最佳答案

与流行的看法相反,将浮点类型(如 double)转换为任何整数类型的行为是未定义,如果值无法放入该整数类型。

所以在你的函数中引入一个 double 确实是一件很糟糕的事情。

如果可以允许截断和环绕效果,为什么不写 return ticks/CLOCKS_PER_SEC; 呢?或者,如果不是,则使用 unsigned long long 作为返回值。

关于c++ - 隐式转换 double 到 unsigned long 溢出 c++,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51131760/

相关文章:

c++ - C++ 中的多个整数类型类

c++ - 什么时候需要 const volatile 对象?

java - 线性回归和 Java 日期

c++ - 将临时值存储为某种数据类型时,算术运算的标准规则是什么?

c++ - strftime 在 iOS 上返回错误的星期几

c++ - 在 CPP 中制作 vector 三元组的简单方法

c++ - 如何使用cmake编译C++共享库项目?

c - C中溢出后有符号和无符号的不一致相等

c++ - 如何执行用c++编写的程序的运行时间?

linux - 如何判断哪个文件首先创建?