GUST NOTCH? DIARY

計算誤差

HP BASIC のスタートレックで、こんな部分があります。


830 X=G[Q1,Q2]*.01
840 K3=INT(X)
850 B3=INT((X-K3)*10)
860 S3=G[Q1,Q2]-INT(G[Q1,Q2]*.1)*10
G[Q1,Q2] は Quadrant の状態を3桁の数値で格納していて、たとえば「215」ならば、クリンゴンが2個、基地が1個、星が5個あることを意味します。で、ここの処理は、その数値から、クリンゴンの数をK3に、基地の数をB3に、星の数をS3に取り出しているわけです。結果として、K3=2, B3=1, S3=5 となります。
これをプチコンでそのまま実装すると、以下のようになります。

X=G(Q1,Q2)*0.01
K3=FLOOR(X)
B3=FLOOR((X-K3)*10)
S3=G(Q1,Q2)-FLOOR(G(Q1,Q2)*0.1)*10
ところが、これを実行すると、K3=2, B3=0, S3=5 となってしまいます。
実は、X=2.1、(X-K3)=0.1、(X-K3)*10=0.996 となってしまい、整数をとると0になってしまっているのです。
これは、固定小数点で計算が行われているために、誤差が発生している影響です*1
0.01をかける代わりに100で割るようにするだけで、意図する X=2.15 が得られるようになります。その結果、B3=1 が得られるようになりますが、このままでも、(X-K3)*10=1.499 となり、誤差が発生してしまいます。
結論からいうと、できるだけ小数は使わない方が良い、ということです。
上記の部分は以下のようにしました。

X=G(Q1,Q2)
K3=FLOOR(X/100)
B3=FLOOR(X/10)-K3*10
S3=X-K3*100-B3*10