Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 50 additions & 1 deletion docs/02algorithms/09error/index.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ $12345 = \underbrace{1.2345}_{\text{仮数部}}\times 10^{\overbrace{-4}^{\text{

## 丸め誤差

### 丸め誤差とは

世の中には、有限桁の小数では表せない数字は多くあります。

まずは、10 進数で考えましょう。
Expand All @@ -41,10 +43,18 @@ $$

このように $0.1_{(10)}$ は 2 進数では有限桁で表せません。

無限桁を扱うことはできないので、有効桁以降を切り捨てることになります。これによって、誤差が出るのが丸め誤差です。
コンピューターは二進数で処理をするので一度二進数に変換しますが、そのときに無限桁を扱うことはできないので、有効桁以降を切り捨てることになります。これによって、誤差が出るのが丸め誤差です。

### 丸め誤差の例

さきほど述べたように $0.1_{(10)}$ を二進数で表すと丸め誤差が発生します。そのため、例えば $0.1\times 3$ を計算すると丸め誤差の影響が現れます。

<ViewSource path="/error/rounding_error.ipynb" />

## 桁落ち

### 桁落ちとは

有効数字 7 桁で $\sqrt{1001}-\sqrt{999}$ を計算することを考えます。

$$
Expand All @@ -65,6 +75,8 @@ $$

このように値がほぼ同じ数値同士で減算をしたときに有効桁数が減少することによって生まれる誤差が桁落ちです。

### 回避策

実は今回の場合は、回避策があります。

$$
Expand All @@ -80,8 +92,20 @@ $$

今回の場合ならば、これで桁落ちを回避できます。

### 桁落ちの例

少し桁を大きくして、実際に確かめてみましょう。

上が桁落ちが起こってしまった例で、下が桁落ちを回避した例です。確かに、上はずれてしまいましたね。

<ViewSource path="/error/cancellation.ipynb" />

<ViewSource path="/error/cancellation_correct.ipynb" />

## 情報落ち

### 情報落ちとは

次の場合、有効数字が 5 桁なら

$$
Expand Down Expand Up @@ -115,4 +139,29 @@ $$

このように、絶対値の大きい数と絶対値の小さい数を加減算したときに、絶対値の小さな数字が無視されてしまうことを情報落ちといいます。

### 回避策

これには、回避策があります。

小さい数を先に足して、その後に大きい数を足せば回避できます。

$$
\begin{align*}
4.000 + 4.000 + 4.000 + 1.000\times 10^4 &= 8.000 + 4.000 + 1.000 \times 10^4 \\
&= 12.000 + 1.000 \times 10^4 \\
&= 1.0012 \times 10^4 \\
&\simeq 1.001 \times 10^4 \\
\end{align*}
$$

これで、有効数字 4 桁で正しい計算ができました。

### 情報落ちの例

10000000000 に 0.0000001 を 10000000 回足すと、10000000001 になります。しかし、上の計算では正しく計算できていません。一方、下の計算では正しく計算できます。

<ViewSource path="/error/loss.ipynb" />

<ViewSource path="/error/loss_error.ipynb" />

<!-- ## 打ち切り誤差 -->
36 changes: 36 additions & 0 deletions static/error/cancellation.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"nbformat": 4,
"nbformat_minor": 2,
"metadata": {},
"cells": [
{
"metadata": {},
"source": [
"import math"
],
"cell_type": "code",
"outputs": [],
"execution_count": null
},
{
"metadata": {},
"source": [
"math.sqrt(100001) - math.sqrt(99999)"
],
"cell_type": "code",
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"0.003162277660237578"
]
},
"metadata": {},
"execution_count": 13
}
],
"execution_count": null
}
]
}
33 changes: 33 additions & 0 deletions static/error/cancellation_correct.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
{
"nbformat": 4,
"nbformat_minor": 2,
"metadata": {},
"cells": [
{
"metadata": {},
"source": [
"import math"
],
"cell_type": "code",
"outputs": [],
"execution_count": null
},
{
"metadata": {},
"source": [
"print(2 / (math.sqrt(100001) + math.sqrt(99999)))"
],
"cell_type": "code",
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"0.0031622776602079072\n"
]
}
],
"execution_count": null
}
]
}
28 changes: 28 additions & 0 deletions static/error/loss.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"nbformat": 4,
"nbformat_minor": 2,
"metadata": {},
"cells": [
{
"metadata": {},
"source": [
"r = 0\n",
"r += 10000000000\n",
"for i in range(10000000):\n",
" r += 0.0000001\n",
"print(r)"
],
"cell_type": "code",
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"10000000000.0\n"
]
}
],
"execution_count": null
}
]
}
28 changes: 28 additions & 0 deletions static/error/loss_correct.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"nbformat": 4,
"nbformat_minor": 2,
"metadata": {},
"cells": [
{
"metadata": {},
"source": [
"r = 0\n",
"for i in range(10000000):\n",
" r += 0.0000001\n",
"r += 10000000000\n",
"print(r)"
],
"cell_type": "code",
"outputs": [
{
"output_type": "stream",
"name": "stdout",
"text": [
"10000000001.0\n"
]
}
],
"execution_count": null
}
]
}
27 changes: 27 additions & 0 deletions static/error/rounding_error.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
{
"nbformat": 4,
"nbformat_minor": 2,
"metadata": {},
"cells": [
{
"metadata": {},
"source": [
"0.1 * 3"
],
"cell_type": "code",
"outputs": [
{
"output_type": "execute_result",
"data": {
"text/plain": [
"0.30000000000000004"
]
},
"metadata": {},
"execution_count": 9
}
],
"execution_count": null
}
]
}