我有这两个值需要四舍五入到两个小数空格

n = 59.9250
n1 = 459.4250

print(round(n, 2))
print(round(n1, 2))

输出

59.92
459.43

有人能解释一下原因吗?有没有一种方法可以像我使用3.6.8版的python时一样将这两种情况进行循环

推荐答案

对于内置的浮点对象,Python使用IEEE-754双精度数字,这意味着绝大多数数字不能准确表示.您可以通过创建一个恰好在限制之下和之上的变量来进行实验测试:

>>> n3 = 1e308 ; n3
1e+308
>>> n3 = 1e309 ; n3
inf

但是,由于CPython是开源的,您也可以通过查看处理浮点对象的代码来验证这一点.在CPython中,它可以在Objects/floatobject.c中找到,您将看到代码中夹杂着用来保存值的Cdouble变量.


因此,如果您在转换站点(如this binary converter)中键入这两个数字,您将看到它们转换为最接近的匹配项,如下所示:

                   |
 59.925       59.92499999.....something
459.925      459.42500000..1..something
                   |

您可以在这里看到,遵循"下一位数为0..4,向上舍入为5..9"的规则,第一位数将取整down59.92,因为下一位数是4(请记住,这里没有特殊的"半途而废"行为,因为两者都不是半途而废).

出于同样的原因,第二个数字将舍入up459.93,因为它的下一个数字是5.

Python documentation for round人实际上提出了这样一种可能性:

注意:对于浮点数,round()的行为可能令人惊讶:例如,round(2.675, 2)等于2.67,而不是预期的2.68.这不是错误:这是因为大多数小数不能精确地表示为浮点数.有关详细信息,请参阅Floating Point Arithmetic: Issues and Limitations.


如果您really想要避免这个问题,您应该跳过使用内置浮点对象及其所有缺点,而 Select 使用Decimal类.

然后,您可以使用它以多种方式处理数字,同时避免损失精度.例如,以下文字记录:

  • 创建exact值(不是某个最接近的浮点匹配);
  • 更改上下文,使其将半个值从零(您可能认为从ROUND_HALF_UP指定符向上舍入到无限大)取整,而不是使用银行家的舍入;然后
  • 将值四舍五入到小数点后两位
>>> d = decimal.Decimal("59.925")
>>> decimal.getcontext().rounding = decimal.ROUND_HALF_UP
>>> round(d, 2)
Decimal('59.93')

Python-3.x相关问答推荐

如何创建多个日志(log)文件

如何在python中有效地使用多处理和pytube库来加快下载速度?

DuckDB:带有嵌套对象的星形表达式

具有多个值的极轴旋转和熔化/取消旋转(反转旋转)操作(Pandas 堆叠/取消堆叠交替/UDF覆盖)

小部件padx和包方法ipadx有什么不同?

如何使用regex将电话号码和姓名从文本字符串中分离出来

如何在当前测试中使用fixture 转换后的数据进行参数化?

Python 列表求和所有出现的保留顺序

Pandas 窗口聚合两个排序表

裁剪复数以解决 exp 中的溢出错误

集合操作:应该只适用于集合,但适用于 dict_keys?

如何将虚拟变量列转换为多列?

Pandas数据单调行为

如何通过python打开文件

如何编写可 Select 充当常规函数的 asyncio 协程?

使用 Python3 与 HDFS 交互的最佳模块是什么?

BeautifulSoup 的 Python 3 兼容性

使用完整路径激活 conda 环境

同步调用协程

将 Python SIGINT 重置为默认信号处理程序