【发布时间】:2017-08-28 20:29:48
【问题描述】:
据我所知,C++ 也依赖于这些问题的 C 标准有以下部分:
当一个整数类型的值被转换为一个真正的浮点类型时,如果被转换的值可以在新的类型中精确地表示,那么它是不变的。如果要转换的值在可以表示但不能准确表示的值范围内,则结果是最接近的较高或最近的较低可表示值,以实现定义的方式选择。如果要转换的值超出可表示的值范围,则行为未定义。
有什么方法可以检查最后一个案例吗?在我看来,最后一个未定义的行为是不可避免的。如果我有一个整数值i 并天真地检查类似
i <= FLT_MAX
我将(除了与精度相关的其他问题)已经触发它,因为比较首先将i 转换为float(在这种情况下或通常转换为任何其他浮动类型),所以如果它超出范围内,我们得到未定义的行为。
或者是否有一些关于整数和浮点类型的相对大小的保证,这意味着“float 总是可以表示 int 的所有值(当然不一定完全正确)”或至少“long double 总是可以容纳一切”这样我们就可以在那种类型中进行比较?不过,我找不到类似的东西。
这主要是一个理论练习,所以我对“在大多数架构上这些转换总是有效”的答案不感兴趣。让我们尝试找到一种方法来检测这种溢出,而不假设任何超出 C(++) 标准的东西! :)
【问题讨论】:
-
64 位 IEEE 浮点可以表示任何
-
这个问题很有趣。我认为它不能以通用方式解决。对于初学者来说,Standard 甚至没有强制要求 IEEE 754 用于浮点数。我认为,您最终会得到特定于实现的逻辑,它知道浮点数是如何表示的以及它们的值是什么。
-
@cdhowie 不要忘记浮点有效数比存储的多一位,因为归一化有效数的 m.s.位始终为
1,因此是隐含的(值0除外)。 -
@old_timer
uintmax_t作为 128 位类型,其值刚好超过FLT_MAX(溢出)是一种真正的可能性,对于使用如此宽的整数和窄 FP。 -
@curiousguy 您没有阅读整个语句,您不能从整数转换中溢出浮点数。现在,我确实以半精度证明了这一点,但是使用典型的整数(32 位、64 位)单上就不会溢出。您可以/将会失去精确度,但这是不同的,这是人们感到困惑的关键。引用的文本以及导致它的情况很容易理解......但实现定义为人们所期望的,否则他们将不得不再写数百页......
标签: c++ c floating-point language-lawyer undefined-behavior