Python中的舍入/舍入标准

Ian*_*ker 5 python matlab rounding

我正在将一个MATLAB代码移植到Python 3.5.1中,我发现了一个浮点数舍入问题.

在MATLAB中,以下数字向上舍入到第6个小数位:

fprintf(1,'%f', -67.6640625);
-67.664063
Run Code Online (Sandbox Code Playgroud)

在Python,而另一方面,下面的数字将被四舍五入至第6位小数:

print('%f' % -67.6640625)
-67.664062
Run Code Online (Sandbox Code Playgroud)

有趣的是,如果该号码是"-67.6000625",则取整起来,即使在Python:

print('%f' % -67.6000625)
-67.600063
Run Code Online (Sandbox Code Playgroud)

......为什么会这样?在Python中舍入/增加的标准是什么?(我相信这与处理十六进制值有关.)

更重要的是,我该如何防止这种差异?我应该创建一个python代码,它可以重现与MATLAB生成的完全相同的输出.

The*_*Cat 4

Python 行为的原因与浮点数在计算机中的存储方式以及 IEEE 定义的标准化舍入规则有关,IEEE 定义了几乎所有现代计算机上使用的标准数字格式和数学运算。

在计算机上以二进制形式有效存储数字的需要导致计算机使用浮点数。这些数字很容易被处理器处理,但缺点是许多十进制数字无法精确表示。这会导致数字有时与我们认为应该的数字有些偏差。

如果我们在 Python 中扩展这些值,而不是截断它们,情况就会变得更清楚:

>>> print('%.20f' % -67.6640625)
-67.66406250000000000000
>>>  print('%.20f' % -67.6000625)
-67.60006250000000704858
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,-67.6640625是一个可以精确表示的数字,但-67.6000625事实并非如此,它实际上要大一些。IEEE 标准为浮点数定义的默认舍入模式规定,上面的任何内容5都应向上舍入,下面的任何内容都应向下舍入。所以对于 的情况-67.6000625,实际上是5加上了一小部分,所以四舍五入。然而,在 的情况下-67.6640625,它恰好等于五,因此抢七规则开始发挥作用。默认的决胜规则是四舍五入到最接近的偶数。由于2是最接近的事件编号,因此它向下舍入为 2。

所以Python遵循浮点标准推荐的方法。那么问题是为什么您的 MATLAB 版本执行此操作。我在我的电脑上使用64位MATLAB R2016a进行了尝试,得到了与Python相同的结果:

>> fprintf(1,'%f', -67.6640625)
-67.664062>>
Run Code Online (Sandbox Code Playgroud)

因此,MATLAB 在某种程度上似乎使用了不同的舍入方法(可能是非标准方法,可能是标准中指定的替代方法之一),并且此后转而遵循与其他人相同的规则。