隐式转换双重到无符号长溢出 c++
Implicit conversion double to unsigned long overflow c++
我正在使用 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(( 返回计算值时,我正在执行从双精度到无符号长整型的隐式转换。 32 位系统的无符号长限制为 2,147,483,647,在 Elapsed(( 返回 2146 后我溢出。
看起来该函数将"ticks"转换为无符号长整型,CLOCK_PER_SEC转换为无符号长整型,然后返回值。当它转换"即时报价"时,它会溢出。
相反,我希望它首先计算"ticks"/CLOCK_PER_SEC的双倍值,然后将其转换为无符号长整型。
在尝试计算更多秒数时,我尝试返回一个无符号的长长数据类型,但变量总是以相同的值 (2147( 溢出。
你能解释一下为什么编译器会转换为无符号长长"先验",为什么即使有无符号长长,它也会以相同的值溢出? 有没有办法以更好的方式编写 Elapsed(( 函数来防止溢出发生?
与普遍的看法相反,如果值无法适应浮点类型(如double
(到任何整型类型,则未定义将浮点类型转换为该整型类型的行为。
因此,在您的函数中引入double
确实是一件糟糕的事情。
如果可以允许截断和环绕效果,为什么不写return ticks / CLOCKS_PER_SEC;
呢?或者,如果没有,请使用unsigned long long
作为返回值。
如果您的系统上,clock_t
是 32 位类型,那么它很可能会像您看到的那样在 2147 秒后环绕。这是预期行为(参考。clock
(。再多的选角也无法绕过这一点。您的代码需要能够处理环绕(通过忽略它或显式说明它(。
当它转换"ticks"时,它会溢出。
不,时钟本身"溢出";转换与它无关。也就是说,转换为double
毫无意义。您的限制是类型clock_t
.请参阅此参考中的注释示例:
clock(( 返回的值可能会在某些实现上环绕。例如,在具有 32 位clock_t的计算机上,它会在 2147 秒或 36 分钟后换行。
一种选择,如果可用的话,是依靠POSIX标准而不是C标准库。它提供了可用于获取以timespec
表示的 CPU 时间clock_gettime
。它不仅不会受到这种溢出的影响(直到更长的时间跨度(,而且还可能具有比clock
更高的分辨率。clock()
的链接参考页面也方便地显示了clock_gettime
的示例用法。
- C++中无符号字符溢出
- 获取隐式转换溢出从无符号到已签名的警告
- 隐式转换双重到无符号长溢出 c++
- 如何检查溢出将字符*[]转换为无符号短短
- 创建具有未定义溢出的无符号 int
- 整数溢出 C++ 即使使用“无符号长整型”也是如此
- 无符号位字段的溢出是否保证环绕
- 有没有办法做 (A*B) mod M 而不会溢出无符号长 A 和 B
- C++大量(无符号长长)的溢出检测
- 在 Linux 32 位上带有 base 36 溢出无符号长长的 strtoull
- 无符号字符模板值溢出
- 溢出的有符号/无符号赋值及其结果
- 无符号Int.溢出
- gcc(TDM-GCC)中的无符号整数溢出错误
- 有没有一种安全的方法可以在不触发溢出的情况下获得有符号整数的无符号绝对值
- 如何抑制来自UBsan的一些无符号整数溢出错误
- C/ c++无符号整数溢出
- 此代码如何产生无符号整数溢出
- 无符号算术和整数溢出
- 发生整数溢出时无符号整数和有符号整数的行为差异