Floating point 每台机器的浮点值保证相同到小数点后多少位?

Floating point 每台机器的浮点值保证相同到小数点后多少位?,floating-point,Floating Point,我需要确保玩家玩我的游戏的演示(保存为击键)在所有机器上都是100%可复制的。浮点数不能保证100%安全(我不能只使用整数,因为游戏的世界不是完全正交的等等),因此不准确不可避免地会在不同的机器上累积,导致播放中断——或者更确切地说:它们可以累积,导致播放中断 我很确定一个浮点数在几个小数位上在不同的系统中是相同的,所以我决定使用浮点数,但将每个浮点数四舍五入到小数位数是多少?…然后保存它们以供以后在程序中使用 为了更加确定,我想我可以制作一个程序,根据“标准结果”列表检查每一个可能产生浮点的计

我需要确保玩家玩我的游戏的演示(保存为击键)在所有机器上都是100%可复制的。浮点数不能保证100%安全(我不能只使用整数,因为游戏的世界不是完全正交的等等),因此不准确不可避免地会在不同的机器上累积,导致播放中断——或者更确切地说:它们可以累积,导致播放中断

我很确定一个浮点数在几个小数位上在不同的系统中是相同的,所以我决定使用浮点数,但将每个浮点数四舍五入到小数位数是多少?…然后保存它们以供以后在程序中使用

为了更加确定,我想我可以制作一个程序,根据“标准结果”列表检查每一个可能产生浮点的计算 查看机器是否适合执行此任务

提前谢谢

0

如果两台机器上的结果之间存在任何偏差,则根据所涉及的数学和算法,在进一步的计算中可能会出现任意大的偏差

一般来说,简单算术运算(加法、减法、乘法、除法和偶数平方根)中的偏差将在一个ULP水平或以下开始。(ULP是最小精度的单位,即值中表示的最低位。)可能会出现这些偏差,因为不同的编译器可能使用不同的精度来计算浮点表达式。例如,即使使用
float
操作数,编译器在计算时也可能使用
double
精度。使用
float
精度的系统将得到与使用
double
精度的系统不同的答案

在更复杂的操作中,例如调用数学库例程,如
pow
sin
log
,可能存在较大的差异。基本上没有商业数学库实现这些具有正确四舍五入结果的例程。(如果使用指定的舍入规则(如始终向上[向上])将精确的数学结果舍入到最近的可表示结果,则正确舍入结果∞] 数学库例程返回的结果相差几个ULP(在质量较差的实现中,有时会相差很多),不同供应商的库将返回不同的结果

为了在不同的平台上再现相同的结果,您需要严格控制浮点运算。很少有编译器提供良好的支持。IEEE 754算法的硬件支持非常广泛,因此您可以通过使用汇编语言和避免各种陷阱来获得可再现的结果。(一个陷阱是将计算分散到多个线程或其他非确定性执行上。另一个陷阱是处理器在默认情况下将低于正常值的值刷新为零,而不是返回正确的IEEE 754结果。)


您会写“我决定使用浮点,但每个浮点都要舍入…”这不是一个少见的概念,但它是有缺陷的。一个问题是它会放大舍入点附近的误差。例如,假设您舍入到1的最近倍数(相当大,但这只是为了说明).因此,2.49将四舍五入为2,2.51将四舍五入为3。如果在一个平台上的结果是2.499,而在另一个平台上的结果是2.501,会发生什么情况?然后将结果四舍五入为2和3。现在,您已经更改了两个平台之间的一个小差异,并使其产生了很大的差异。

非常感谢您的回答。那么,我应该如何着手进行改进100%可复制(在“理论和计算”水平上,即忽略量子力学等的潜在影响)我正在用LÖVE编写的游戏演示录像机?对于舍入问题,如果我只是将它们放在地板上怎么办?这可能是一个非常愚蠢的说法,但我很累,而且脱水(像往常一样)所以请耐心等待。@wolfboyft:在多个平台上获得相同的浮点结果并不容易,也不能用注释来回答。您可以在堆栈溢出中搜索“[浮点]再现性”对于一些信息。底线是,您需要使用汇编语言或至少超出标准编程语言的扩展来控制机器状态,您必须将编译器限制为严格符合IEEE-754的操作,而不需要额外的精度或压缩,并且您不能依赖任何供应商数学库或其他特定于平台的操作数学库。这不是一项容易的任务。@wolfboyft:Floor将不起作用。这只是另一种舍入方法。任何舍入方法的问题是,存在一些点x,其中一个略低于x的值向下舍入,而一个略高于x的值向上舍入,因此x附近的任何计算错误都会被放大。浮点用于近似连续(实数)算法,因此应用任何非连续函数(如舍入/截断)都与此冲突。