maximum float + x 是否定义了行为?

Is maximum float + x defined behavior?

我使用以下方法进行了快速测试:

float x = std::numeric_limits<float>::max();
x += 0.1;

这导致 x == std::numeric_limits::max() 所以它没有超过限制。

不过,这是否保证跨编译器和平台的行为? HLSL 呢?

Is this guaranteed behavior across compilers and platforms though?

不,行为未定义。标准说(强调我的):

5 Expressions
....
If during the evaluation of an expression, the result is not mathematically defined or not in the range of representable values for its type, the behavior is undefined. [ Note: most existing implementations of C++ ignore integer overflows. Treatment of division by zero, forming a remainder using a zero divisor, and all floating point exceptions vary among machines, and is usually adjustable by a library function. —end note ]

@user2079303所述,实际上我们可以减少限制:

it is not undefined if std::numeric_limits<float>::has_infinity. Which is often true. In that case, the result is merely unspecified.

std::numeric_limits<T>::max() 的值定义为类型 T 可表示的最大有限值(参见 18.3.2.4 [numeric.limits.members] 第 4 段)。这样,这个问题实际上变成了多个子问题:

  1. 是否可以创建大于 std::numeric_limits<T>::max() 的值,即是否存在无穷大?
  2. 如果是,需要将哪个值添加到 std::numeric_limits<T>::max() 以获得无穷大?
  3. 如果没有,是否定义了行为?

C++ 没有指定浮点格式,不同的格式可能对结果有不同的看法。特别是,我认为浮点格式不需要定义无穷大的值。例如,IBM Floating Points do not have an infinity. On the other hand the IEEE 754 确实有无穷大表示。

因为算术类型的溢出可能是未定义的行为(参见 5 [expr] 第 4 段)而且我没有看到任何浮点类型的排除。因此,如果没有无穷大,该行为将是未定义的行为。至少,可以测试一个类型是否确实有无穷大(参见 18.3.2.3 [numeric.limits] 第 35 段),在这种情况下操作不能溢出。

如果有无穷大,我 认为 将任何值添加到 std::numeric_limits<T>::max() 都会得到无穷大。但是,要确定是否确实如此,需要深入研究相应的浮点规范。我可以想象,如果值太小而不相关,IEEE 754 可能会忽略添加,就像将 0.1 添加到 std::numeric_limits<T>::max() 的情况一样。我也可以想象它决定它总是溢出到无穷大。