如何保持浮点/双精度运算的确定性?

2024-10-01 22:33:23 发布

您现在位置:Python中文网/ 问答频道 /正文

如果我们使用双精度和浮点运算的算法,在Python和C、x86和x64linux和Windows计算机以及ARM微控制器中,我们如何保证结果是相同的呢?在

我们使用的算法是:

  • 双倍+双倍
  • 双倍+浮动
  • 双倍经验
  • 浮动*浮动

在同一台计算机上,为x86和x64mingw编译它会得到不同的结果。这个算法需要大量的数学运算,所以任何一个小错误最终都会产生不同的结果。在

现在,ARM mcu实现给出了与x86相同的结果,但是在看到这些之后,我不确定是否正确。在

编辑

在这种情况下,精度损失不是问题,只要在所有实现中都是相同的

编辑2

我发现这些链接非常有用,评论中已经有一些提示:


Tags: 算法编辑windows计算机错误精度数学经验
2条回答

If we use algorithms with double and float arithmetic, how can we guarantee that the results are the same running it in Python and C, in x86 and x64 Linux and Windows computers and ARM microcontrollers?

一般来说,你不能这样做,除非你小心地执行你自己的FP操作。如果您使用的是各种语言的标准运算符和库以及底层的浮点硬件,则无法确保结果在不同实现之间的精确再现性。在

首先,浮点数的内部表示存在问题。C没有指定要使用的表示形式,即使所有其他条件都相同,这意味着您不能依赖于运行在不同实现(例如x86_64和ARM)上的同一个C程序来计算相同的结果。在

实际上,现在大多数人都使用ieee754浮点格式,CPython使用底层C实现的double类型来支持其浮点。然而,即便如此,IEEE也允许一致性实现之间存在一定的少量变化。即使是要求严格遵守IEEE规范的指令和编译选项也不能完全解决这个问题。在

此外,您还指定要在C和Python中同时处理double和{},但是Python没有{}的本机模拟。它的本机浮点格式(可能)对应于Cdouble。对不同的浮点数据类型执行的操作必然会产生不同的结果,即使操作数在数值上是相等的,而且这种差异可能会在类型转换中持续存在,例如将double结果转换为float。在

在(机器)代码生成级别,还需要考虑其他细节,例如中间结果是否或何时从FPU寄存器复制到主存(可能涉及舍入)以及执行操作的顺序。在

We re using an algorithm that uses:

double + double
double + float
double exp(double)
float * float

如果您想最小化计算值的差异,那么从选择一种浮点数据类型开始,并在任何地方使用它。为了保证Python和C实现之间的一致性,应该是double。在

您还应该考虑禁用可能会更改FP操作求值顺序的所有优化。这可能是所有的优化。如果您的C编译器中有一些选项可以用来执行严格的IEEE一致性,那么就打开这些选项。在

您还应该在所有相关平台上测试exp()函数的等价性。您可能需要提供自己的实现。在


无论你做什么,你都应该认识到,如果你的不同实现产生了不同的结果,尽管在某种算法意义上都是正确的,那么这本身就是一个结果。它告诉你一些关于计算的真实精度的信息。在

千万不要忘记,大多数计算机FP操作都会产生近似的结果,因此即使您设法让所有实现都产生相同的结果,但这并不意味着这些结果在绝对意义上比其他邻近的FP值更正确。如果数字一致性是一个要求,那么您应该根据结果的特定精度来量化它,以一种能够提供这种精度的方式实现您的算法,并且忽略精度高于所选精度的差异。在

这很难。双打和浮标在C或C++标准中没有形式化,其精度取决于编译器/ CPU的实现。例如,float和double都允许相同。在

< C++ 17草案(其他论文中的相似) basic.fundamental

There are three floating-point types: float, double, and long double. The type double provides at least as much precision as float, and the type long double provides at least as much precision as double. The set of values of the type float is a subset of the set of values of the type double; the set of values of the type double is a subset of the set of values of the type long double. The value representation of floating-point types is implementation-defined. [ Note: This document imposes no requirements on the accuracy of floating-point operations; see also [support.limits]. — end note ]

<>我认为C或C++标准中没有提到{a2}。在

Python派生了它,其中浮点类型在C实现中被引用,而形式化是also up to implementaion

There are three distinct numeric types: integers, floating point numbers, and complex numbers. In addition, Booleans are a subtype of integers. Integers have unlimited precision. Floating point numbers are usually implemented using double in C;

相关问题 更多 >

    热门问题