【问题标题】:Round-off / round-up criteria in PythonPython中的舍入/舍入标准
【发布时间】:2016-08-27 15:37:33
【问题描述】:

我正在将 MATLAB 代码移植到 Python 3.5.1,但发现了浮点舍入问题。

在 MATLAB 中,以下数字会向上四舍五入到小数点后第 6 位:

fprintf(1,'%f', -67.6640625);
-67.664063

另一方面,在 Python 中,以下数字会关闭到小数点后 6 位:

print('%f' % -67.6640625)
-67.664062

有趣的是,如果数字是 '-67.6000625',那么即使在 Python 中它也会向上四舍五入:

print('%f' % -67.6000625)
-67.600063

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

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

【问题讨论】:

  • 我很好奇,所以我也在 numpy 中查找了 this 的行为。我得到的很奇怪。 np.around(a,6)(a 是您的第一个值)产生 -67.664062000000001。您尝试的第二个值产生:-67.600061999999994。 The official python documentation 解释了这种行为。
  • 我尝试了C和Octave,它们都打印-67.664062,和Python一样。
  • 考虑到浮点比较一直是多么棘手(比如 3.0*2.2 != 2.0*3.3),我首先要质疑该项目的可行性。比较两个浮点数的最佳做法始终是将差异与某个容差进行比较。
  • 我建议不要使用隐式的舍入形式。相反,请确保您的代码正在执行您期望的操作。 This answer 是对你想做的事情的一个很好的总结。

标签: python matlab rounding


【解决方案1】:

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

需要在计算机上以二进制有效地存储数字,这导致计算机使用浮点数。这些数字很容易让处理器使用,但缺点是许多十进制数字cannot be exactly represented。这会导致数字有时与我们认为的数字有所偏差。

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

>>> print('%.20f' % -67.6640625)
-67.66406250000000000000
>>>  print('%.20f' % -67.6000625)
-67.60006250000000704858

如您所见,-67.6640625 是一个可以精确表示的数字,但-67.6000625 不是,它实际上要大一些。浮点数的默认舍入模式defined by the IEEE stanard 表示高于5 的任何值都应向上舍入,低于5 的任何值都应向下舍入。所以对于-67.6000625的情况,实际上是5加上少量,所以向上取整。但是,在-67.6640625 的情况下,它正好等于5,因此一个抢七规则开始发挥作用。默认的决胜局规则是四舍五入到最接近的偶数。由于2 是最近的事件编号,因此向下舍入为二。

所以 Python 遵循浮点标准推荐的方法。那么,问题是为什么您的 MATLAB 版本 这样做。我在我的电脑上用 64bit MATLAB R2016a 试了一下,结果和 Python 一样:

>> fprintf(1,'%f', -67.6640625)
-67.664062>>

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

【讨论】:

  • 哇,解释得很好。我完全相信。是的,我使用的是 MATLAB R2011b,所以有点老。我认为 MATLAB 永远是对的,但我错了。一件好事是我不必为这个问题修复我的 Python 代码。 ;-) 非常感谢!
猜你喜欢
  • 2012-08-12
  • 2012-06-19
  • 1970-01-01
  • 1970-01-01
  • 2021-11-20
  • 1970-01-01
  • 2011-10-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多