1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

無限小数を乗算して丸め誤差が起きた計算事例

Last updated at Posted at 2020-01-20

概要

以下のような問題を解いていた。

1000m先に信号機がある。この信号は、15秒ごとに赤になり、また15秒後に緑に戻ることを繰り返す。
ある自動車がこのエリアにs km/hで突入し定速で走り続けたが、この信号を緑で通過したい。
0<= s <= 200とするとき、これを実現できる最大の速度を求めよ。ただし、sは整数とする。

尚、信号はこの地点に到達した瞬間に緑であれば通過できるし、赤であれば通過できないとする。
この信号はエリアに入った瞬間に緑になったものとする。

# 考え方
まず、ある信号機のある地点についた時間tが$ 0 \leqq t \lt 15$や$ 30 \leqq t \lt 45$, $ 60 \leqq t \lt 75$であれば通過でき、$ 15 \leqq t \lt 40$や$ 45 \leqq t \lt 60$であれば通過できない。つまり、tを15で除算した結果を切り下げたとき、偶数であればOK(通過), 奇数であればNG(通れない)となる。

次に、スピードは時速(km/h)であり、信号機の地点は(m)であるので単位を合わせる必要がある。
求めたいのは200km/h以下でこの信号機を通過できるかなので、200->1までforで回して通過できる条件を満たせばよい。これをシミュレートする。

d = 1000
for s in range(70, 0, -1): #70km/h -> 1km/hまでシミュレート
    # 信号までの距離[m] を 速度(秒速かつm単位)で割る
    if ( ( d // (s / 3600 * 1000)) ) % 15 == 0:
        print("[1]OK! s = {0}".format(s))
        break

# 上の式を変形したもの
for s in range(70, 0, -1):
    if ( ( d * 3600 / 1000) // s ) % 15 == 0:
        print("[2]OK! s = {0}".format(s))
        break

"""
[1]OK! s = 40
[2]OK! s = 60
"""

[1]と[2]は式を変形したもので、結果は同じ値でないとおかしいが、なぜか結果が異なる。

\frac{d}{\frac{s}{3600} 1000} \Leftrightarrow \frac{d \frac{3600}{1000}}{s}

手で計算すると、例えばs=60のとき、

\frac{1000}{\frac{60}{3600} 1000} = \frac{3600}{60} = 60

となり、$60 / 15 = 4$で偶数のため通過できるのが正しい。式をPython3で計算すると、

[1]>>> (1000 // (60 / 3600 * 1000))
59.0
[2]>>> (1000  * 3600 / 1000) // 60
60.0

となり結果が一致しない。なぜこうなるかというと、

[1]の式の一部
>>> 60/3600
0.016666666666666666
>>> 60/3600*1000
16.666666666666668
>>> a=60/3600*1000
>>> 1000 / a
59.99999999999999

というように、60/3600を1000で倍にして無限小数が丸められた結果、結果が60にならず、59.999となってしまったからである。
例えば

>>> 1000 / (60 / 3600) / 1000
60.0

のようにしても、正しく答えは得られる。

まとめ

無限小数を乗算すると、まるめが出てしまうので注意しなければならない。

1
0
4

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?