在python中向下舍入到2位小数

Sur*_*mar 6 python rounding

我需要向下舍入,它应该是两位小数.
试过以下,

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)


MSe*_*ert 8

似乎您要截断而不是四舍五入。

一种简单的方法是将楼层划分//和常规划分相结合/

>>> 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应从字符串创建以避免中间不精确的浮点数。但是,从不同FractionDecimal具有精度有限,所以有很多的显著数字也将成为不准确的值。

但是,“四舍五入”只是可用的选项之一。可用的舍入模式列表很广泛:

舍入模式

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,则从零舍入。否则舍入为零。


use*_*863 7

这是一个不受浮点精度误差影响的简单函数

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)


Ben*_*han 6

使用 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