Python 中的四舍五入/四舍五入标准
Round-off / round-up criteria in Python
我正在将 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:
中,它也会被四舍五入 up
print('%f' % -67.6000625)
-67.600063
... 为什么会这样?
round-off/up in Python 的标准是什么?
(我相信这与处理十六进制值有关。)
更重要的是,我怎样才能避免这种差异?
我应该创建一个 python 代码,它可以重现与 MATLAB 生成的输出完全相同的输出。
python 行为的原因与浮点数在计算机中的存储方式以及 IEEE 定义的标准化舍入规则有关,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 版本 不这样做。我在我的电脑上用 64 位 MATLAB R2016a 试了一下,结果和 Python:
一样
>> fprintf(1,'%f', -67.6640625)
-67.664062>>
因此,似乎 MATLAB 在某些时候使用了不同的舍入方法(可能是非标准方法,可能是标准中指定的替代方法之一),并且此后切换为遵循与以下相同的规则其他人。
我正在将 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:
中,它也会被四舍五入 upprint('%f' % -67.6000625)
-67.600063
... 为什么会这样? round-off/up in Python 的标准是什么? (我相信这与处理十六进制值有关。)
更重要的是,我怎样才能避免这种差异? 我应该创建一个 python 代码,它可以重现与 MATLAB 生成的输出完全相同的输出。
python 行为的原因与浮点数在计算机中的存储方式以及 IEEE 定义的标准化舍入规则有关,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 版本 不这样做。我在我的电脑上用 64 位 MATLAB R2016a 试了一下,结果和 Python:
一样>> fprintf(1,'%f', -67.6640625)
-67.664062>>
因此,似乎 MATLAB 在某些时候使用了不同的舍入方法(可能是非标准方法,可能是标准中指定的替代方法之一),并且此后切换为遵循与以下相同的规则其他人。