実験で使う計算機を作って遊んでいましたが、不具合が見つかりまくったので、その修正の過程で調べたことをまとめています。
不具合は主に以下の2つです。
- getElementById()で取得したElementのvalueプロパティの型によるもの
- JavaScriptにおける小数点の計算の誤差によるもの
1. getElementById()で取得したElementのvalueプロパティ
getElementById()メソッドはElementオブジェクトを返します。問題になったのは、Elementオブジェクトのvalueプロパティの型はなんだろうということです。
答えはHTMLInputElementにあり、valueプロパティはString型になります。
この値を変数に渡すのですが、inputで入力した値が整数ならば数値型と推論され、小数ならば文字列型と推論されます。
JavaScriptの型推論に明るくないのでなんとも言えませんが、バグ回避のために、入力された値を数値として扱いたい場合はNumberを用いたり、小数ならばparseFloatを用いて明示的に型変換を行うべきだと思いました。
2. 小数点の計算誤差とその回避
有名な話ですが、JavaScriptでは0.1 + 0.2=0.30000000000000004となります。これは計算誤差によるものです。
よって、これを小数を一度文字列にすることで回避します。
次のページのアルゴリズムを参考にしています。JavaScriptでの小数点の計算の誤差について
以下のコードは加算の場合の例になります。
ライブラリを使う手や、うまいこと四捨五入を用いる方法などもあるようです。
競技プログラミングでよく使う、計算する値を予め整数にする方法はJavaScriptだとうまく行かないことがあるようです。
3. おわりに
久しぶりに競技プログラミングの問題を解いたらコードをバグらせまくって死にました。最近JavaScriptを書いたり、GASを書いたり、VBAを書いたりして遊びすぎたようです。ちゃんと精進します。
ところでJavaScriptの動的型付けが苦手なので、TypeScriptどうや?って言われたのですが、どうなんだろう?いい感じならTypeScriptで書き換えたいところ。