---
tags: Python
---
# Rounding, Decimal
## round
`round` 在 Python2 和 Python3 的定義不同。
Python2 使用四捨五入:
> Values are rounded to the closest multiple of 10 to the power minus ndigits; if two multiples are equally close, rounding is done **away from 0**.
>
> [name=[`round(number[, ndigits])` / Python2](https://docs.python.org/2.7/library/functions.html#round)]
Python3 使用 Bankers rounding 四捨六入五成雙:
> Values are rounded to the closest multiple of 10 to the power minus ndigits; if two multiples are equally close, rounding is done **toward the even choice**.
>
> [name=[`round(number[, ndigits])` / Python3](https://docs.python.org/3/library/functions.html#round)]
文件上也有提及到,有時會出現預料不到的情形,因為大多數的十進制小數都不能精確地表示為二進制小數:
> The behavior of `round()` for floats can be surprising: for example, `round(2.675, 2)` gives `2.67` instead of the expected `2.68`. This is not a bug: it’s a result of the fact that **most decimal fractions can’t be represented exactly as a float**.
```python
>>> Decimal(2.675)
Decimal('2.67499999999999982236431605997495353221893310546875')
>>> Decimal('2.675')
Decimal('2.675')
```
> If you’re in a situation where you care which way your decimal halfway-cases are rounded, you should consider using the decimal module. Incidentally, the decimal module also provides a nice way to “see” the exact value that’s stored in any particular Python float.
>
> [name=[Floating Point Arithmetic: Issues and Limitations / Python](https://docs.python.org/2.7/tutorial/floatingpoint.html#tut-fp-issues)]
## [Decimal](https://docs.python.org/3/library/decimal.html)
Decimal 預設也是採用`ROUND_HALF_EVEN` (四捨六入五成雙),可以透過 rounding 給予 `ROUND_HALF_UP` (四捨五入)調整方式。
```python
from decimal import (
Decimal,
ROUND_HALF_UP,
)
Decimal('0.645').quantize(Decimal('0.00'), rounding=ROUND_HALF_UP)
```
> [`decimal.ROUND_HALF_EVEN`](https://docs.python.org/3/library/decimal.html#decimal.ROUND_HALF_EVEN): Round to nearest with ties going to nearest even integer.
>
> [`decimal.ROUND_HALF_UP`](https://docs.python.org/3/library/decimal.html#decimal.ROUND_HALF_UP): Round to nearest with ties going away from zero.
## 四捨六入五成雙
四捨五入會造成整體的數字偏大,而 Banker's Rounding 的方法會讓整體數值偏差更小。
| `num` | `round(num)` | Description |
|---------|--------------|-------------|
| `5.4` | `5` | 小於 5 捨去 |
| `5.6` | `6` | 大於 5 進位 |
| `5.5` | `6` | 如果保留位數的後一位如果是 5,而且 5 後面沒有數,則看前一位數,奇進偶捨 |
| `6.5` | `6` |
| `6.51` | `7` | 如果保留位數的後一位如果是 5,而且 5 後面仍有數,則進位 |