【发布时间】:2018-02-20 14:28:57
【问题描述】:
我正在研究使用 Python 内置解决方案和 SymPy 等其他一些外部库的不同舍入方法,在此过程中我偶然发现了一些需要帮助来理解其背后原因的案例。
Ex-1:
print(round(1.0065,3))
输出: 1.006
在第一种情况下,使用 Python 内置的舍入函数,输出是 1.006 而不是 1.007,我可以理解这不是错误,因为 Python 会舍入到最接近的偶数,这就是所谓的银行家舍入。
这就是为什么我从一开始就开始寻找另一种控制舍入行为的方法。通过快速搜索,我发现了可以轻松处理十进制值并有效舍入的 decimal.Decimal 模块正在使用 quantize(),如下例所示:
from decimal import Decimal, getcontext, ROUND_HALF_UP
context= getcontext()
context.rounding='ROUND_HALF_UP'
print(Decimal('1.0065').quantize(Decimal('.001')))
输出:1.007
这是一个非常好的解决方案,但唯一的问题是在长数学表达式中硬编码并不容易,因为我需要将每个数字转换为字符串,然后在使用十进制后我将按照表格中的形式传递进动的“0.001”,而不是像内置回合那样直接写“3”。
在寻找另一个解决方案时,我发现 SymPy,我已经在我的脚本中使用了很多,它提供了一些非常强大的功能,可能会有所帮助,但是当我尝试它时,输出并不像我预期的那样。
Ex-1 使用 SymPy sympify():
print(sympify(1.0065).evalf(3))
输出:1.01
Ex-2 使用 SymPy N(标准化):
print(N(1.0065,3))
输出:1.01
首先输出有点奇怪,但经过调查后,我意识到 N 和 sympify 已经正确执行舍入,但舍入到有效数字,而不是小数位。
问题来了:
由于我可以使用 Decimal 对象 getcontext().rounding='ROUND_HALF_UP' 来更改舍入行为,有没有办法更改 N 并将舍入行为简化为小数位而不是有效数字?
【问题讨论】: