在所有平台和处理器架构中,从float到int的转换是否一致?

时间:2017-05-27 00:48:11

标签: c++ c floating-point

我正在研究一种依赖于所谓的“浮点确定性”的多人游戏,换句话说,所有计算的结果必须与运行游戏的每个人完全相同。这实质上意味着不使用IEEE 754浮点,因为操作可能会导致不同的值,具体取决于舍入模式,使用的融合乘法加法或反平方根指令,不同的libc实现等等。

所以我已经去了所有基本算术运算甚至一些超越函数的定点版本。但是我还是想使用浮点文字来配置游戏变量。在这样做的过程中,我最终得到了一些看起来像是从浮点转换为固定点的代码:

explicit NetFixedPoint(float val)
{
  static const StorageType kOne = StorageType(1) << FractionalBits;
  m_Value = ((StorageType)(val * kOne));
}

这会在所有平台和处理器架构中给出相同的结果吗?

3 个答案:

答案 0 :(得分:5)

简短的回答是“不”。

浮点表示是实现定义的,在将浮点值转换为其他类型时,也会出现浮点类型之间提到的问题类型。

此外,int的许多属性 - 包括大小,它可以表示的值范围以及表示(例如位组织)也是实现定义的。

净效果是从floatint的某些转换在实现之间可靠地工作,而有些则不会。将float转换为int时,有些值会向下舍入。 float也可以表示比int更大的值范围,并且转换“超出范围”值可能会产生未定义的行为。

不要尝试使用浮点文字初始化变量,而应考虑使用字符串文字(并将值包装在双引号中)。权衡是解析字符串以初始化变量的开销。

答案 1 :(得分:4)

如果浮点值(截断为零)在整数类型中可表示,则严格定义从浮点到整数的转换。如果没有,那么它是未定义的。

其他答案似乎是故意钝的;如果您完全依赖于任何类型的浮点确定性,您需要假设一个符合IEEE-754的实现,而不是C ++标准允许不符合的实现的虚假无理通用性。 IEEE-754。在这种情况下,假设你的编译器没有错误,那么你就有一定程度的确定性,而你的关注点将放在浮点转换为int之外的区域。

答案 2 :(得分:1)

C ++实现从浮点值到整数值的转换的细节大多是一个没有实际意义的点,当C ++标准没有给出关于什么是浮点值的保证。

C ++标准仅保证:

  

[basic.fundamental]

     

有三种浮点类型:float,double和long double。   double类型提供至少与float一样多的精度   类型long double提供至少与double一样多的精度。该   float类型的值集是该组值的子集   双重类型; double类型的值集是。的子集   long double类型的值集。 的值表示   浮点类型是实现定义的。

(强调我的)

当&#34;浮点类型的表示的值是实现定义的&#34;时,它几乎排除了一切。对于不同C ++实现之间的浮点到整数值转换一致性,您没有任何保证,因为该标准不保证您可以保证不同的C ++实现&#39;浮点值首先会有一致的值表示!

如果你需要明确定义的浮点语义,你唯一可行的选择是使用专用的,任意精度的数学库,比如Gnu MP,你可以完全控制浮点精度和值转换。