20

我注意到两点:

  1. std::numeric_limits<float>::max()+(a small number) 给出: std::numeric_limits<float>::max()

  2. std::numeric_limits<float>::max()+(a large number喜欢:std::numeric_limits<float>::max()/3) 给出信息。

为什么会有这种差异?1 或 2 是否会导致溢出并因此导致未定义的行为?

编辑:用于测试的代码:

1.

float d = std::numeric_limits<float>::max();
float q = d + 100;
cout << "q: " << q << endl;

2.

float d = std::numeric_limits<float>::max();
float q = d + (d/3);
cout << "q: " << q << endl;
4

2 回答 2

15

形式上,行为是未定义的。但是,在具有 IEEE 浮点数的机器上,舍入后溢出将导致Inf. 但是,精度是有限的,四舍五入后的结果FLT_MAX + 1FLT_MAX

您可以看到与低于 的值相同的效果FLT_MAX。尝试类似:

float f1 = 1e20;     // less than FLT_MAX
float f2 = f1 + 1.0;
if ( f1 == f2 ) ...

if评估为true,至少使用 IEEE 算术。(确实存在,或者至少已经存在,机器 float具有足够的精度if来评估 到 false,但它们在今天并不常见。)

于 2013-07-11T08:25:13.450 回答
1

这取决于你在做什么。如果浮点“溢出”出现在直接返回的表达式中,即

return std::numeric_limits::max() + std::numeric_limits::max();

该操作可能不会导致溢出。我引用了 C 标准 [ISO/IEC 9899:2011]:

return 语句不是赋值。子条款 6.5.16.1 的重叠限制不适用于函数返回的情况。浮点值的表示可能比类型隐含的范围或精度更宽;可以使用强制转换来消除这种额外的范围和精度。

有关更多详细信息,请参见此处

于 2013-07-11T08:27:16.733 回答