假设 IEEE-754一致性,当通过 double 传输时, float 是否保证被保留?
换句话说,是否总是满足以下断言?
int main()
{
float f = some_random_float();
assert(f == (float)(double)f);
}
假设 f
可以获取 IEEE 定义的任何特殊值,例如 NaN 和 Infinity。
根据 IEEE 的说法,是否存在这样的情况:assert 会被满足,但在通过 double 传输后没有保留确切的位级表示?
代码片段在 C 和 C++ 中均有效。
最佳答案
您甚至不需要假设 IEEE。 C89 在 3.1.2.5 中说:
The set of values of the type
float
is a subset of the set of values of the typedouble
所有其他的 C 和 C++ 标准都说了同样的话。据我所知,NaN 和无穷大是“float
类型的值”,尽管用作操作数时具有一些特殊情况规则的值。
float -> double -> float 转换恢复 float
的原始值的事实(通常)遵循以下事实:数字转换都保留该值,如果它在目标中可表示输入。
位级表示是一个稍微不同的问题。想象一下,有一个 float
的值,它有两种不同的按位表示。那么 C 标准中的任何内容都不会阻止 float -> double -> float 转换从一个转换到另一个。在 IEEE 中,除非有填充位,否则“实际值”不会发生这种情况,但我不知道 IEEE 是否排除了具有不同按位表示的单个 NaN。无论如何,NaN 不会与自己比较,因此除了可能将它们转换为字符串之外,也没有标准的方法来判断两个 NaN 是“相同的 NaN”还是“不同的 NaN”。这个问题可能没有实际意义。
需要注意的一点是编译器的不一致模式,在这种模式下,它们会“隐藏”超精确的值,例如,中间结果留在浮点寄存器中并在不进行舍入的情况下重复使用。我不认为这会导致您的示例代码失败,但是一旦您执行浮点 ==
这就是您开始担心的那种事情。
关于c++ - 当通过 C/C++ 中的 double 传输时,是否保证保留 float ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14773142/