2016-06-15 42 views
2

我試圖將十進制數的金錢數湊到最接近的0.05。現在,我這樣做:圓python十進制到最接近的0.05

def round_down(amount): 
    amount *= 100 
    amount = (amount - amount % 5)/Decimal(100) 
    return Decimal(amount) 

def round_up(amount): 
    amount = int(math.ceil(float(100 * amount)/5)) * 5/Decimal(100) 
    return Decimal(amount) 

有什麼辦法,我可以做到這一點更優雅無需處理(使用量化也許)使用python小數花車?

+0

爲什麼不使用python中的回合? –

+0

@SeekAddo。我將如何四捨五入到最接近的0.05?我還需要控制舍入方向(即我需要向上舍入/向下舍入)。 – gurch101

+0

def round_num(金額): print(round(金額,2)) round_num(23.045954)會給你23.05,讓我問一下,你想怎樣才能像@ gurch101 –

回答

5

用浮漂,只需使用round(x * 2, 1)/2。不過,這並不能控制舍入方向。

使用Decimal.quantize你也得到了四捨五入的類型和方向完全控制(Python的3.5.1):

>>> from decimal import Decimal, ROUND_UP 

>>> x = Decimal("3.426") 
>>> (x * 2).quantize(Decimal('.1'), rounding=ROUND_UP)/2 
Decimal('3.45') 

>>> x = Decimal("3.456") 
>>> (x * 2).quantize(Decimal('.1'), rounding=ROUND_UP)/2 
Decimal('3.5') 
+0

聰明。謝謝! – gurch101

0

首先要注意這個問題(意外舍去)僅有時時發生數字直接低於(你的四捨五入的數字的左邊)有一個5

>>> round(1.0005,3) 
1.0 
>>> round(2.0005,3) 
2.001 
>>> round(3.0005,3) 
3.001 
>>> round(4.0005,3) 
4.0 
>>> round(1.005,2) 
1.0 
>>> round(5.005,2) 
5.0 
>>> round(6.005,2) 
6.0 
>>> round(7.005,2) 
7.0 
>>> round(3.005,2) 
3.0 
>>> round(8.005,2) 
8.01 

但有一個簡單的解決方案,我發現,似乎總是工作,並且不依賴於額外的庫import。解決的辦法是增加一個其中X是你正在嘗試使用上round1數字符串的長度。

>>> round(0.075,2) 

0.07 

>>> round(0.075+10**(-2*6),2) 

0.08 

啊哈!因此,基於這一點,我們可以方便的包裝函數,它是獨立的,不需要額外的import電話......

def roundTraditional(val,digits): 
    return round(val+10**(-len(str(val))-1)) 

基本上,這增加了保證比字符串的至少給定的數字小的值,你'正試圖使用​​round。通過添加少量它保存的round的在大多數情況下的行爲,而現在如果不如一個數字被四捨五入爲確保是5它四捨五入,如果是4它幾輪下來。

使用10**(-len(val)-1)的方法是有意的,因爲它是您可以添加的最大的小數字來強制轉換,同時也確保即使缺少小數點.,添加的值也不會更改舍入。我可以只使用10**(-len(val))與condiditional if (val>1)減去1更多...但它更簡單,只是始終減去1因爲這將不會改變太多小數此變通辦法可以妥善處理的適用範圍。如果你的值達到了類型的限制,這種方法將失敗,這將失敗,但對於幾乎整個範圍的有效小數值,它應該工作。

您還可以使用decimal庫來做到這一點,但我提出的包裝比較簡單,可以在某些情況下是首選。


編輯:感謝Blckknght的指出了5邊緣的情況下對某些值here只發生。