[英]Python 3 Decimal rounding half down with ROUND_HALF_UP context
[英]round down to 2 decimal in python
我需要四舍五入,它應該是小數點后兩位。
嘗試了以下,
a = 28.266
print round(a, 2)
28.27
但期望值僅為 28.26。
好像你需要floor
:
import math
math.floor(a * 100)/100.0
# 28.26
看來您想要截斷,而不是四舍五入。
一個簡單的方法是結合樓層划分//
和常規划分/
:
>>> a = 28.266
>>> a // 0.01 / 100
28.26
除了常規除法之外,您還可以乘法(如cmc的評論中所述):
>>> a // 0.01 * 0.01
28.26
同樣,您可以創建一個函數來四舍五入到其他更多/更少的小數。 但是因為浮點數是不精確的數字,所以這可能會導致不准確。
def round_down(value, decimals):
factor = 1 / (10 ** decimals)
return (value // factor) * factor
print(round_down(28.266, 2))
# 28.26
但正如所說,它並不完全准確:
for i in range(0, 8):
print(i, round_down(12.33333, i))
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
還有其他(更精確的)方法:
fraction
模塊的解決方案 fraction
可以比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
並使用我對浮點數進行的測試:
for i in range(0, 8):
print(i, round_down(12.33333, i))
0 12
1 123/10
2 1233/100
3 12333/1000
4 123333/10000
5 1233333/100000
6 1233333/100000
7 1233333/100000
然而,創建Fraction
不會神奇地修復不精確的float
,因此通常應該從字符串或“分子-分母對”而不是從 float 創建Fraction
。
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
這為四舍五入提供了更合理的結果:
for i in range(0, 8):
print(i, round_down(12.33333, i))
0 12
1 12.3
2 12.33
3 12.333
4 12.3333
5 12.33333
6 12.333330
7 12.3333300
與Fraction
一樣,應從字符串創建Decimal
以避免中間不精確的浮點數。 但是,從不同的Fraction
與Decimal
具有精度有限,所以有很多的顯著數字也將成為不准確的值。
然而,“四舍五入”只是可用選項之一。 可用的舍入模式列表非常廣泛:
舍入模式
decimal.ROUND_CEILING
向無窮大decimal.ROUND_CEILING
。
decimal.ROUND_DOWN
向零decimal.ROUND_DOWN
。
decimal.ROUND_FLOOR
向 -Infinitydecimal.ROUND_FLOOR
。
decimal.ROUND_HALF_DOWN
到最接近的關系,並趨向於零。
decimal.ROUND_HALF_EVEN
入到最接近的整數,關系到最近的偶數。
decimal.ROUND_HALF_UP
到最接近的關系,從零開始。
decimal.ROUND_UP
入。
decimal.ROUND_05UP
如果向零四舍五入后的最后一位數字為 0 或 5,則從零四舍五入; 否則向零舍入。
使用 Python 3.9,您可以使用 quantize()
from decimal import *
>>> Decimal('7.325').quantize(Decimal('.01'), rounding=ROUND_DOWN)
Decimal('7.32')
我測試了上面的答案並且它起作用了。 但我發現這個 1 班輪很簡單。 所以我也在這里寫下我的答案。
試試這個:
import math
a = 28.266
print((math.floor(a * 100)) / 100.0)
輸出:
28.26
這是一個不受浮點精度誤差影響的簡單函數
def truncate_float(n, places):
return int(n * (10 ** places)) / 10 ** places
測試:
>>> truncate_float(28.266, 3)
28.266
>>> truncate_float(28.266, 2)
28.26
>>> truncate_float(28.266, 1)
28.2
一般情況下,還有一種更簡單的方法,即在四舍五入之前減去少量,如下所示:
a = 28.269
digits = 2
print(round(a - 0.5/10**digits, digits))
這是基於直覺,將浮點數四舍五入到最接近的整數的一種方法是加上 0.5,然后截斷。 上述解決方案通過減去所需精度允許的最小“刻度”的一半,然后四舍五入來實現相反的效果。
您可以在代碼中使用的簡單功能。 此函數也可用於整數樓層數。
import math
def floorDecimal(number, decimal):
return math.floor(number * pow(10, decimal))/pow(10, decimal)
使用示例:
number = 256.789
newNumber = floorDecimal(number, 2) # newNumber is 256.78
newNumber = floorDecimal(number, -2) # newNumber is 200
這是我使用f表示浮點數和d表示小數位數的函數
from math import floor
def floor_decimal(f, d):
n = 10 ** d
return floor(f * n) / n
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.