如果我们使用双精度和浮点运算的算法,在Python和C、x86和x64linux和Windows计算机以及ARM微控制器中,我们如何保证结果是相同的呢?在
我们使用的算法是:
在同一台计算机上,为x86和x64mingw编译它会得到不同的结果。这个算法需要大量的数学运算,所以任何一个小错误最终都会产生不同的结果。在
现在,ARM mcu实现给出了与x86相同的结果,但是在看到这些之后,我不确定是否正确。在
编辑
在这种情况下,精度损失不是问题,只要在所有实现中都是相同的
编辑2
我发现这些链接非常有用,评论中已经有一些提示:
一般来说,你不能这样做,除非你小心地执行你自己的FP操作。如果您使用的是各种语言的标准运算符和库以及底层的浮点硬件,则无法确保结果在不同实现之间的精确再现性。在
首先,浮点数的内部表示存在问题。C没有指定要使用的表示形式,即使所有其他条件都相同,这意味着您不能依赖于运行在不同实现(例如x86_64和ARM)上的同一个C程序来计算相同的结果。在
实际上,现在大多数人都使用ieee754浮点格式,CPython使用底层C实现的
double
类型来支持其浮点。然而,即便如此,IEEE也允许一致性实现之间存在一定的少量变化。即使是要求严格遵守IEEE规范的指令和编译选项也不能完全解决这个问题。在此外,您还指定要在C和Python中同时处理},但是Python没有{}的本机模拟。它的本机浮点格式(可能)对应于C
double
和{double
。对不同的浮点数据类型执行的操作必然会产生不同的结果,即使操作数在数值上是相等的,而且这种差异可能会在类型转换中持续存在,例如将double
结果转换为float
。在在(机器)代码生成级别,还需要考虑其他细节,例如中间结果是否或何时从FPU寄存器复制到主存(可能涉及舍入)以及执行操作的顺序。在
如果您想最小化计算值的差异,那么从选择一种浮点数据类型开始,并在任何地方使用它。为了保证Python和C实现之间的一致性,应该是
double
。在您还应该考虑禁用可能会更改FP操作求值顺序的所有优化。这可能是所有的优化。如果您的C编译器中有一些选项可以用来执行严格的IEEE一致性,那么就打开这些选项。在
您还应该在所有相关平台上测试
exp()
函数的等价性。您可能需要提供自己的实现。在无论你做什么,你都应该认识到,如果你的不同实现产生了不同的结果,尽管在某种算法意义上都是正确的,那么这本身就是一个结果。它告诉你一些关于计算的真实精度的信息。在
千万不要忘记,大多数计算机FP操作都会产生近似的结果,因此即使您设法让所有实现都产生相同的结果,但这并不意味着这些结果在绝对意义上比其他邻近的FP值更正确。如果数字一致性是一个要求,那么您应该根据结果的特定精度来量化它,以一种能够提供这种精度的方式实现您的算法,并且忽略精度高于所选精度的差异。在
这很难。双打和浮标在C或C++标准中没有形式化,其精度取决于编译器/ CPU的实现。例如,float和double都允许相同。在
< C++ 17草案(其他论文中的相似) basic.fundamental <>我认为C或C++标准中没有提到{a2}。在Python派生了它,其中浮点类型在C实现中被引用,而形式化是also up to implementaion
相关问题 更多 >
编程相关推荐