浮点类型转换是否会导致未定义行为?
根据C++标准定义,浮点转换指的是两种浮点类型之间不属于提升的转换。最简单的示例就是double转float:
double d = 0.1; float f = d;
标准在[conv.double]中规定:
浮点类型的纯右值可以转换为另一种浮点类型的纯右值。
若源值可在目标类型中精确表示,则转换结果为该精确表示。
若源值位于目标类型的两个相邻值之间,则转换结果为这两个值中由实现定义的一个。
否则,行为未定义。
浮点提升所允许的转换不属于浮点转换的范畴。
在上述示例中,源值无法在目标类型中精确表示:d的值为0.10000000000000001,而f的值(通常)为0.10000000149011612,把f转换回double后并不等于d。不过该源值位于目标类型的两个相邻值之间——也就是f和前一个可表示的float值0.099999994039535522。因此f的值可以是这两个值中的任意一个,而由于0.10000000149011612更接近0.10000000000000001,这通常是实现会选择的值。
我的疑问在于最后一种情况:
否则,行为未定义。
是否存在会导致转换行为未定义的源值?由于浮点类型有+∞和-∞的表示,我认为不存在既无法精确表示也不位于两个相邻目标值之间的源值:任何double值要么是可精确表示的float值(包括NaN),要么位于-∞和+∞之间,即处于两个相邻float值之间。
那么这个“否则”条款的意义何在?它是否是为了涵盖那些被视为浮点类型但并非float、double或long double的特殊类型?float、double和long double之间的转换是否会导致未定义行为?
内容的提问来源于stack exchange,提问作者Nelfeal

