Python Language -  format() built-in Floating Point Rounding（浮動小数点数の端数処理 - 丸め）

Python では、他の多くの言語と同様に浮動小数点数における端数の丸めが行われます。

__15. Floating Point Arithmetic: Issues and Limitations__
https://docs.python.org/3.9/tutorial/floatingpoint.html

__The Perils of Floating Point__
https://www.lahey.com/float.htm

Python では IEEE 754 の `Round to nearest, ties to even（最近接丸め（偶数）= 偶数丸め（= 銀行家の丸め =Bankers' Rounding ））` を採用しています。
__IEEE 754__
https://en.wikipedia.org/wiki/IEEE_754#Rounding_rules

※ decimal 等で丸めの方法を変更することも可能です。
__Rounding modes__
https://docs.python.org/3.9/library/decimal.html#rounding-modes

ここでは、典型的な丸めとして format() built-in の例をご紹介します。
__format() built-in__
https://docs.python.org/3.9/library/functions.html#format

#### 環境
以下の Python 3.9 / Linux 環境で確認します。
```shell
$ uname -si
Linux x86_64

$ python3.9 -V
Python 3.9.13

$ python3.9
Python 3.9.13 (main, Jun 15 2022, 11:24:50)
[GCC 8.5.0 20210514 (Red Hat 8.5.0-13)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>>
```

#### float 型
以下のような float 型を使用します。
```shell
>>> for D in [(x / 1000 + 1.11) for x in range(1, 10)]:
...     print(type(D), D)
...
<class 'float'> 1.111
<class 'float'> 1.112
<class 'float'> 1.113
<class 'float'> 1.114
<class 'float'> 1.115
<class 'float'> 1.116
<class 'float'> 1.117
<class 'float'> 1.118
<class 'float'> 1.119
```
この数字を `format()` を使用して小数点第2位で丸めます。
```shell
>>> for D in [(x / 1000 + 1.11) for x in range(1, 10)]:
...     print(type(D), D, "-> {:.2f}".format(D))
...
<class 'float'> 1.111 -> 1.11
<class 'float'> 1.112 -> 1.11
<class 'float'> 1.113 -> 1.11
<class 'float'> 1.114 -> 1.11
<class 'float'> 1.115 -> 1.11
<class 'float'> 1.116 -> 1.12
<class 'float'> 1.117 -> 1.12
<class 'float'> 1.118 -> 1.12
<class 'float'> 1.119 -> 1.12
```
偶数丸めにも関わらず、`1.115` が `1.11` になっていることが分かります。
ここで、`1.115` を [] 内に小数点20桁表示すると、実際の値は `1.11499999999999999112` であり、偶数丸めに合致していることが分かります。
```shell
>>> for D in [(x / 1000 + 1.11) for x in range(1, 10)]:
...     print(type(D), D, "[{:.20f}]".format(D), "-> {:.2f}".format(D))
...
<class 'float'> 1.111 [1.11099999999999998757] -> 1.11
<class 'float'> 1.112 [1.11200000000000009948] -> 1.11
<class 'float'> 1.113 [1.11299999999999998934] -> 1.11
<class 'float'> 1.114 [1.11400000000000010125] -> 1.11
<class 'float'> 1.115 [1.11499999999999999112] -> 1.11
<class 'float'> 1.116 [1.11600000000000010303] -> 1.12
<class 'float'> 1.117 [1.11699999999999999289] -> 1.12
<class 'float'> 1.118 [1.11800000000000010481] -> 1.12
<class 'float'> 1.119 [1.11899999999999999467] -> 1.12
>>>
```
このようなケースが以下に記載されています。
__15. Floating Point Arithmetic: Issues and Limitations__
https://docs.python.org/3.9/tutorial/floatingpoint.html

上記を回避するために、Decimal() を使用してみます。
__decimal — Decimal fixed point and floating point arithmetic__
https://docs.python.org/3.9/library/decimal.html

```shell
>>> from decimal import Decimal
>>> for D in [Decimal(str(x / 1000 + 1.11)) for x in range(1, 10)]:
...     print(type(D), D, "[{:.20f}]".format(D), "-> {:.2f}".format(D))
...
<class 'decimal.Decimal'> 1.111 [1.11100000000000000000] -> 1.11
<class 'decimal.Decimal'> 1.112 [1.11200000000000000000] -> 1.11
<class 'decimal.Decimal'> 1.113 [1.11300000000000000000] -> 1.11
<class 'decimal.Decimal'> 1.114 [1.11400000000000000000] -> 1.11
<class 'decimal.Decimal'> 1.115 [1.11500000000000000000] -> 1.12
<class 'decimal.Decimal'> 1.116 [1.11600000000000000000] -> 1.12
<class 'decimal.Decimal'> 1.117 [1.11700000000000000000] -> 1.12
<class 'decimal.Decimal'> 1.118 [1.11800000000000000000] -> 1.12
<class 'decimal.Decimal'> 1.119 [1.11900000000000000000] -> 1.12
```
`1.115` の値は `1.115（小数点20桁表示では1.11500000000000000000）` となり、丸めの結果が `1.12` で偶数丸めに合致していることが分かります。