python decimal.quantize()參數rounding的各參數解釋與行為


我最開始其實是由於疑惑ROUND_FLOOR和 ROUND_DOWN的表現區別才看了一波文檔,但是感覺拉出一票以前沒有留意過的東西。

貼一個decimal文檔里面的解釋:

ROUND_CEILING (towards Infinity),
ROUND_DOWN (towards zero),
ROUND_FLOOR (towards -Infinity),
ROUND_HALF_DOWN (to nearest with ties going towards zero),
ROUND_HALF_EVEN (to nearest with ties going to nearest even integer),
ROUND_HALF_UP (to nearest with ties going away from zero), or
ROUND_UP (away from zero).
ROUND_05UP (away from zero if last digit after rounding towards zero would have been 0 or 5; otherwise towards zero)

 

直接閱讀上面的解釋十分抽象,下面我結合例子來解釋一下在正負數不同的情況下 他們究竟有着什么樣的行為

首先給出一組負數的后一位超過5的數據:

input:
from decimal import *

x = Decimal('-3.1415926535') + Decimal('-2.7182818285')
print x
print x.quantize(Decimal('1.0000'), ROUND_HALF_EVEN)
print x.quantize(Decimal('1.0000'), ROUND_HALF_DOWN)
print x.quantize(Decimal('1.0000'), ROUND_CEILING)
print x.quantize(Decimal('1.0000'), ROUND_FLOOR)
print x.quantize(Decimal('1.0000'), ROUND_UP)
print x.quantize(Decimal('1.0000'), ROUND_DOWN)

output:
-5.8598744820
-5.8599
-5.8599
-5.8598
-5.8599
-5.8599
-5.8598

ROUND_HALF_EVENT 和 ROUND_HALF_DOWN:EVENT是quansize的默認設置值,可以通過getcontext()得到,EVENT四舍五入進了一位,DOWN為接近最近的0進了一位。

ROUND_CEILING 和 ROUND_FLOOR:CEILING超過5沒有進位是因為它傾向正無窮,FLOOR為了總是變得更小所以進了一位。

ROUND_UP 和 ROUND_DOWN:UP始終進位,DOWN始終不會進位。。

 

再多對比一組后一位沒有超過5的數據:

input:
from decimal import *

x = Decimal('-3.14159265') + Decimal('-2.7182818285')
print x
print x.quantize(Decimal('1.00000'), ROUND_HALF_EVEN)
print x.quantize(Decimal('1.00000'), ROUND_HALF_DOWN)
print x.quantize(Decimal('1.00000'), ROUND_CEILING)
print x.quantize(Decimal('1.00000'), ROUND_FLOOR)
print x.quantize(Decimal('1.00000'), ROUND_UP)
print x.quantize(Decimal('1.00000'), ROUND_DOWN)

output:
-5.8598744785
-5.85987
-5.85987
-5.85987
-5.85988
-5.85988
-5.85987

ROUND_HALF_EVENT 和 ROUND_HALF_DOWN:EVENT是quansize的默認設置值,可以通過getcontext()得到,EVENT由於達不到四舍五入所以不進位,DOWN同樣也不進位。

ROUND_CEILING 和 ROUND_FLOOR:CEILING傾向正無窮不進位,FLOOR即使沒有超過5,但是為了總是變得更小進了一位。

ROUND_UP 和 ROUND_DOWN:UP始終進位,DOWN始終不會進位。。

 

正數部分后面數大於5的情況:

input:
y = Decimal('3.1415926535') + Decimal('2.7182818285')
print y
print y.quantize(Decimal('1.0000'), ROUND_HALF_EVEN)
print y.quantize(Decimal('1.0000'), ROUND_HALF_DOWN)
print y.quantize(Decimal('1.0000'), ROUND_CEILING)
print y.quantize(Decimal('1.0000'), ROUND_FLOOR)
print y.quantize(Decimal('1.0000'), ROUND_UP)
print y.quantize(Decimal('1.0000'), ROUND_DOWN)

output:
5.8598744820
5.8599
5.8599
5.8599
5.8598
5.8599
5.8598

ROUND_HALF_EVENT 和 ROUND_HALF_DOWN:EVENT是quansize的默認設置值,可以通過getcontext()得到,EVENT由於達到四舍五入所以進位,DOWN同樣進位。

ROUND_CEILING 和 ROUND_FLOOR:CEILING正數始終進位,FLOOR在正數則始終不會進位。

ROUND_UP 和 ROUND_DOWN:UP始終進位,DOWN始終不會進位。

 

正數部分后面數小於5的情況:

input:
y = Decimal('3.1415926535') + Decimal('2.7182818285')
print y
print y.quantize(Decimal('1.00000'), ROUND_HALF_EVEN)
print y.quantize(Decimal('1.00000'), ROUND_HALF_DOWN)
print y.quantize(Decimal('1.00000'), ROUND_CEILING)
print y.quantize(Decimal('1.00000'), ROUND_FLOOR)
print y.quantize(Decimal('1.00000'), ROUND_UP)
print y.quantize(Decimal('1.00000'), ROUND_DOWN)

output:
5.8598744820
5.85987
5.85987
5.85988
5.85987
5.85988
5.85987

ROUND_HALF_EVENT 和 ROUND_HALF_DOWN:EVENT是quansize的默認設置值,可以通過getcontext()得到,EVENT由於沒有達到四舍五入所以不進位,DOWN同樣不進位。

ROUND_CEILING 和 ROUND_FLOOR:CEILING正數始終進位,FLOOR在正數則始終不會進位。

ROUND_UP 和 ROUND_DOWN:UP始終進位,DOWN始終不會進位。

 

總結:

其實這里我們通過上面一組例子可以發現,正數的行為非常可預期也非常簡單,負數的情況稍復雜,有些函數就是設計為負數在某些情況中使用的。正數中無法重現的ROUND_DOWN和ROUND_FLOOR的區別,ROUND_DOWN是無論后面是否大於5都不會管保持原狀,而Floor在正數中的行為也是如此,但是在負數中為了傾向無窮小,所以無論是否大於5,他都會變得更小而進位。反而ROUND_UP和ROUND_DOWN的行為是最可預期的,那就是無論后面數大小,UP就進位,DOWN就始終不進位。

 

Reference:

https://docs.python.org/2/library/decimal.html#decimal.getcontext    decimal官方文檔2.7.11


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM