## DEV Community

codemee

Posted on • Updated on

# Python 的 round() 與 decimal 模組

`round()` 是 Python 內建的捨入法函式, 它的規格如下：

``````round(數值, 位數)
``````

``````>>> round(2.2251, 2)
2.23
``````

## `round()` 的擇『偶』規則

``````>>> round(4.5, 0)
4.0
``````

``````>>> round(3.5, 0)
4.0
``````

## 指定負的位數

`round()` 的第 2 個參數可以是負數, 0 是個位數、-1 是十位數、-2 是百位數、...以此類推, 例如：

``````>>> round(4351.3455, 0)
4351.0
>>> round(4351.3455, -1)
4350.0
>>> round(4351.3455, -2)
4400.0
>>> round(4351.3455, -3)
4000.0
``````

## `round()` 是看整個數值而非只看下一位數

``````>>> round(2.2251, 2)
2.23
``````

## 浮點數潛在的誤差

``````>>> "{:1.5f}".format(2.2250)
'2.22500'
>>> "{:1.20f}".format(2.2250)
'2.22500000000000008882'
``````

``````>>> round(2.2250, 2)
2.23
``````

2.2250 明明與 2.23 及 2.22 等距, 依據『擇偶』規則, 應該選偶數的 2.22, 但結果是 2.23, 這就是因為實際的值比 2.2250 大, 離 2.23 比較近的關係。再來看一個例子：

``````>>> round(2.2350, 2)
2.23
``````

``````>>> "{:1.20f}".format(2.2350)
'2.23499999999999987566'
``````

## 使用 decimal 模組的 Decimal 類別

``````>>> import decimal
>>> round(decimal.Decimal('2.2350'), 2)
Decimal('2.24')
``````

``````>>> round(decimal.Decimal(2.2350), 2)
Decimal('2.23')
``````

### 變更捨入法

`decimal` 模組提供有 `Context` 類別的物件, 可透過 `getcontext()` 函式取得, 控制捨進位方式等等, 例如：

``````>>> c = decimal.getcontext()
>>> c.rounding = decimal.ROUND_UP
``````

``````>>> round(decimal.Decimal(2.2350), 2)
Decimal('2.24')
>>> round(decimal.Decimal(2.2310), 2)
Decimal('2.24')
``````

## 客製類別的捨入法

``````>>> import math
>>> class MyFloat:
...     def __init__(self, f):
...             self.f = f
...     def __round__(self, d=0):
...             f = self.f * pow(10, d)
...             f = float(math.ceil(f))
...             return f * pow(10, -d)
...
>>>
``````

``````>>> round(MyFloat(2.13), 1)
2.2
>>> round(MyFloat(2.13), 0)
3.0
``````