我需要向下舍入,它应该是两位小数.
试过以下,
a = 28.266
print round(a, 2)
Run Code Online (Sandbox Code Playgroud)
28.27
但预期值仅为28.26.
Psi*_*dom 12
好像你需要floor:
import math
math.floor(a * 100)/100.0
# 28.26
Run Code Online (Sandbox Code Playgroud)
似乎您要截断而不是四舍五入。
一种简单的方法是将楼层划分//和常规划分相结合/:
>>> a = 28.266
>>> a // 0.01 / 100
28.26
Run Code Online (Sandbox Code Playgroud)
除了常规的除法运算之外,您还可以相乘(如cmc的注释所示):
>>> a // 0.01 * 0.01
28.26
Run Code Online (Sandbox Code Playgroud)
同样,您可以创建一个函数以四舍五入为其他更多/更少的小数。但是由于浮点数是不精确的数字,因此可能导致不正确。
def round_down(value, decimals):
factor = 1 / (10 ** decimals)
return (value // factor) * factor
print(round_down(28.266, 2))
# 28.26
Run Code Online (Sandbox Code Playgroud)
但是正如所说的,它并不完全准确:
for i in range(0, 8):
print(i, round_down(12.33333, i))
Run Code Online (Sandbox Code Playgroud)
0 12.0
1 12.3
2 12.33
3 12.333
4 12.333300000000001 # weird, but almost correct
5 12.33332 # wrong
6 12.33333
7 12.33333
Run Code Online (Sandbox Code Playgroud)
但是,还有其他(更精确的)方法:
fraction模块的解决方案A fraction可以代表比A 更精确的十进制数float。然后,可以使用Psidom提到的“相乘,然后相乘,然后相除”的方法,但精度要高得多:
import fractions
import math
a = 28.266
def round_down(value, decimals):
factor = 10 ** decimals
f = fractions.Fraction(value)
return fractions.Fraction(math.floor(f * factor), factor)
print(round_down(28.266, 2))
# 1413/50 <- that's 28.26
Run Code Online (Sandbox Code Playgroud)
使用我对浮点数所做的测试:
for i in range(0, 8):
print(i, round_down(12.33333, i))
Run Code Online (Sandbox Code Playgroud)
0 12
1 123/10
2 1233/100
3 12333/1000
4 123333/10000
5 1233333/100000
6 1233333/100000
7 1233333/100000
Run Code Online (Sandbox Code Playgroud)
但是,创建a Fraction不会神奇地解决不精确的问题float,因此通常应从Fraction字符串或“分子-分母”对创建而不是从float进行创建。
decimal模块的解决方案您也可以使用该decimal模块,该模块提供多种舍入模式,包括舍入。
对于此演示,我使用上下文管理器来避免全局更改小数舍入模式:
import decimal
def round_down(value, decimals):
with decimal.localcontext() as ctx:
d = decimal.Decimal(value)
ctx.rounding = decimal.ROUND_DOWN
return round(d, decimals)
print(round_down(28.266, 2)) # 28.26
Run Code Online (Sandbox Code Playgroud)
得出四舍五入的结果更为合理:
for i in range(0, 8):
print(i, round_down(12.33333, i))
Run Code Online (Sandbox Code Playgroud)
0 12
1 12.3
2 12.33
3 12.333
4 12.3333
5 12.33333
6 12.333330
7 12.3333300
Run Code Online (Sandbox Code Playgroud)
与Fractiona一样,Decimal应从字符串创建以避免中间不精确的浮点数。但是,从不同Fraction的Decimal具有精度有限,所以有很多的显著数字也将成为不准确的值。
但是,“四舍五入”只是可用的选项之一。可用的舍入模式列表很广泛:
舍入模式
decimal.ROUND_CEILING朝着无限前进。
decimal.ROUND_DOWN向零舍入。
decimal.ROUND_FLOOR向-Infinity方向舍入。
decimal.ROUND_HALF_DOWN四舍五入到最接近的零关系。
decimal.ROUND_HALF_EVEN四舍五入到最接近的偶数。
decimal.ROUND_HALF_UP四舍五入到最接近的关系,领带从零开始。
decimal.ROUND_UP四舍五入。
decimal.ROUND_05UP如果四舍五入后的最后一位数字为0或5,则从零舍入。否则舍入为零。
这是一个不受浮点精度误差影响的简单函数
def truncate_float(n, places):
return int(n * (10 ** places)) / 10 ** places
Run Code Online (Sandbox Code Playgroud)
测试:
>>> truncate_float(28.266, 3)
28.266
>>> truncate_float(28.266, 2)
28.26
>>> truncate_float(28.266, 1)
28.2
Run Code Online (Sandbox Code Playgroud)
使用 Python 3.9,您可以使用 quantize()
from decimal import *
>>> Decimal('7.325').quantize(Decimal('.01'), rounding=ROUND_DOWN)
Decimal('7.32')
Run Code Online (Sandbox Code Playgroud)
我测试了上面的答案并且它起作用了。但我发现这个 1 班轮很简单。所以我也在这里写下我的答案。
来源:https : //docs.python.org/3/library/decimal.html