【发布时间】:2019-07-02 03:15:41
【问题描述】:
考虑这段代码:
#include <iostream>
#include <climits>
#include <fenv.h>
int main()
{
feenableexcept(FE_INVALID);
double d = INT_MAX * 2.0f;
int i = (int)d; // it throws here fp exception and terminates. Why ?
std::cout << i << std::endl;
return 0;
}
这里首先要注意的是,将 double 转换为 int 会导致临时值溢出(大于 INT_MAX),这当然通常是未定义的行为。
但我更担心的是,这里的 FP 异常可以通过将FE_INVALID 常量标志传递给feenableexcept 函数来捕获。
从cpp_reference可以看出FE_INVALID和溢出根本没有关系。
为什么这里的整数溢出会导致fp异常?
这是因为 UB 的性质吗?
【问题讨论】:
-
INT_MAX * 2.0f可以表示为float吗?你为什么用2.0f而不是2.0? -
@SidS 确实有点奇怪的选择,但它适合。
FLT_MAX通常是 3.40282e+38。 -
@BaummitAugen 当然可以,但是会缺少精度?
INT_MAX * 2.0f / 2可能不等于INT_MAX。 -
@BaummitAugen,在我的系统上这个代码:
cout << INT_MAX << ' ' << int(INT_MAX * 2.0f / 2) << ' ' << int(INT_MAX * 2.0 / 2) << endl;输出2147483647 -2147483648 2147483647 -
请注意常见的混淆来源。浮点异常不是 C++ 异常,因此不会被抛出。浮点数的人称错误为异常,但它们是两个不同的东西。
标签: c++ c++11 exception floating-point integer-overflow