通过C/C++中的双精度传输时,是否可以保留浮点数?

Kri*_*ege 34 c c++ floating-point double ieee-754

假设符合IEEE-754标准,是否保证在通过双重传输时保留浮动?

换句话说,以下断言是否会始终满足?

int main()
{
    float f = some_random_float();
    assert(f == (float)(double)f);
}
Run Code Online (Sandbox Code Playgroud)

假设f可以获取IEEE定义的任何特殊值,例如NaN和Infinity.

根据IEEE的说法,是否存在断言将被满足的情况,但是在通过double传输之后不能保留确切的位级表示?

代码段在C和C++中都有效.

Ste*_*sop 30

你甚至不需要假设IEEE.C89在3.1.2.5中说:

该类型的值float集是该类型的值集的子集double

每个其他C和C++标准都说明了相同的东西.据我所知,NaNs和无穷大是"类型的float值",尽管在用作操作数时具有一些特殊情况规则的值.

float - > double - > float转换float的事实是,如果数值转换在目标类型中可表示,则数值转换都会保留值,从而恢复跟随的原始值(通常).

比特级表示略有不同.想象一下,它的值float有两个不同的按位表示.那么C标准中的任何内容都不会阻止float - > double - > float转换从一个切换到另一个.在IEEE中,除非存在填充位,否则"实际值"不会发生,但我不知道IEEE是否排除了具有不同按位表示的单个NaN.NaNs无论如何都不等于它们,所以也没有标准方法来判断两个NaN是否是"相同的NaN"或"不同的NaN",而不是将它们转换为字符串.这个问题可能没有实际意义.

需要注意的一件事是编译器的不一致模式,其中它们保持"隐藏"的超精确值,例如中间结果留在浮点寄存器中并重复使用而不进行舍入.我认为这不会导致您的示例代码失败,但是一旦您进行浮点运算==,就会开始担心这种情况.


Ale*_*nze 16

来自C99:

6.3.1.5实数浮动类型
1当浮点数被提升为double或long double,或者double被提升为long double时,其值不变.
2当double被降级为float时,long double被降级为double或float,或者以更高的精度和范围表示的值比其语义类型所需的值(见6.3.1.8)被显式转换为其语义类型,如果转换后的值可以用新类型表示,它没有变化......

我认为,这可以保证float-> double-> float转换将保留原始的float值.

该标准还定义了宏INFINITYNAN7.12 Mathematics <math.h>:

4宏INFINITY扩展为float类型的常量表达式,表示正无穷大或无符号无穷大(如果可用); 否则为float类型的正常量,在转换时溢出.
5当且仅当实现支持float类型的安静NaN时,才定义宏NAN.它扩展为float类型的常量表达式,表示安静的NaN.

因此,有这样的特殊值的规定,转换也可能对它们起作用(包括负无穷大和负零).