<blockquote>
<p>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?</p>
</blockquote>
<p>一般来说,你不能这样做,除非你小心地执行你自己的FP操作。如果您使用的是各种语言的标准运算符和库以及底层的浮点硬件,则无法确保结果在不同实现之间的精确再现性。在</p>
<p>首先,浮点数的内部表示存在问题。C没有指定要使用的表示形式,即使所有其他条件都相同,这意味着您不能依赖于运行在不同实现(例如x86_64和ARM)上的同一个C程序来计算相同的结果。在</p>
<p>实际上,现在大多数人都使用ieee754浮点格式,CPython使用底层C实现的<code>double</code>类型来支持其浮点。然而,即便如此,IEEE也允许一致性实现之间存在一定的少量变化。即使是要求严格遵守IEEE规范的指令和编译选项也不能完全解决这个问题。在</p>
<p>此外,您还指定要在C和Python中同时处理<code>double</code>和{<cd3>},但是Python没有{<cd3>}的本机模拟。它的本机浮点格式(可能)对应于C<code>double</code>。对不同的浮点数据类型执行的操作必然会产生不同的结果,即使操作数在数值上是相等的,而且这种差异可能会在类型转换中持续存在,例如将<code>double</code>结果转换为<code>float</code>。在</p>
<p>在(机器)代码生成级别,还需要考虑其他细节,例如中间结果是否或何时从FPU寄存器复制到主存(可能涉及舍入)以及执行操作的顺序。在</p>
<blockquote>
<p>We re using an algorithm that uses:</p>
<pre><code>double + double
double + float
double exp(double)
float * float
</code></pre>
</blockquote>
<p>如果您想最小化计算值的差异,那么从选择一种浮点数据类型开始,并在任何地方使用它。为了保证Python和C实现之间的一致性,应该是<code>double</code>。在</p>
<p>您还应该考虑禁用可能会更改FP操作求值顺序的所有优化。这可能是所有的优化。如果您的C编译器中有一些选项可以用来执行严格的IEEE一致性,那么就打开这些选项。在</p>
<p>您还应该在所有相关平台上测试<code>exp()</code>函数的等价性。您可能需要提供自己的实现。在</p>
<hr/>
<p>无论你做什么,你都应该认识到,如果你的不同实现产生了不同的结果,尽管在某种算法意义上都是正确的,那么这本身就是一个结果。它告诉你一些关于计算的真实精度的信息。在</p>
<p>千万不要忘记,大多数计算机FP操作都会产生近似的结果,因此即使您设法让所有实现都产生相同的结果,但这并不意味着这些结果在绝对意义上比其他邻近的FP值更正确。如果数字一致性是一个要求,那么您应该根据结果的特定精度来量化它,以一种能够提供这种精度的方式实现您的算法,并且忽略精度高于所选精度的差异。在</p>