我使用以下方法进行了快速测试:
float x = std::numeric_limits<float>::max();
x += 0.1;
导致x == std :: numeric_limits :: max()所以它没有超过限制。
这是跨编译器和平台的保证行为吗?那么HLSL呢?
答案 0 :(得分:3)
这是跨编译器和平台的保证行为吗?
不,行为未定义。标准说(强调我的):
5个表达
....
如果在评估表达式期间,结果未在数学上定义或不在范围内 其类型的可表示值, 行为未定义 。 [注意:大多数现有的C ++实现 忽略整数溢出。除以零处理,使用零除数形成余数, all 浮点异常因机器 而异,通常可通过库函数进行调整。 - 结束记录]
正如 @ user2079303 所提到的,在实践中我们可以减少限制:
如果
std::numeric_limits<float>::has_infinity
,则 未定义。这通常是真的。在这种情况下,结果是 仅仅未指定 。
答案 1 :(得分:1)
std::numeric_limits<T>::max()
的值被定义为类型T
可表示的最大有限值(见18.3.2.4 [numeric.limits.members]第4段)。因此,这个问题实际上变成了多个子问题:
std::numeric_limits<T>::max()
的值,即是否存在无穷大?std::numeric_limits<T>::max()
才能获得无穷大?C ++没有指定浮点格式,不同格式可能不同意结果。特别是,我不认为浮点格式需要为无穷大定义一个值。例如,IBM Floating Points没有无穷大。另一方面,IEEE 754确实具有无限表示。
由于算术类型的溢出可能是未定义的行为(参见5 [expr]第4段),并且我没有看到浮点类型的任何排除。因此,如果没有无穷大,行为将是未定义的行为。至少,可以测试一个类型是否具有无穷大(见18.3.2.3 [numeric.limits]第35段),在这种情况下,操作不能溢出。
如果有无穷大,我认为向std::numeric_limits<T>::max()
添加任何值会让你无限。然而,确定是否确实需要挖掘相应的浮点规范。我可以想象,如果值太小而不能与0.1
添加std::numeric_limits<T>::max()
,那么IEEE 754可能会忽略添加。我还可以想象它决定它总是溢出到无限。