普通のプログラマであれば、整数で値を決めたい場合、浮動小数点演算を使いることはない。x
の30%
といわれれば x * 0.3
とせず(精度指定文字リテラルは省く & 小数以下は切り捨てるとして) x * 30 / 100
としたりして、とにかくなるべく使わない。
しかし 今回 AngularJS の入力フォームからパーセントな値を受け取った(バリデータも使えるし、htmlのstep属性とかも使えて便利だしね)ら、 JavaScript は IEEE 754 の double しかない世界である。
Chrome のデバッグコンソールを出して以下を実行すればすぐ試せる。
1 2 |
|
こ、、、こんな精度いるぅ? 言われてみると俺の愛する C++ は精度指定なし小数点付き数字は精度 double だった。そして Java もそうである。最近は Java をやっててたまたまIDE開いていたのでそれで試す。
1 2 |
|
つらい。どれぐらいつらいかというとこのぐらいのつらさであった
1 2 3 4 5 |
|
16.40
を 100倍して小数以下切り捨てたら 1639
! IEEE 754 だとそうだっつーのか! マジかよ! 信じない! Java 先生にお伺いをたててやる!
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
|
やはり IEEE 754 の double の世界ではこれが正しいらしい。ちなみに以下のような有様である。
1 2 3 4 5 6 |
|
今回得た教訓は
- JavaScript はどうがんばっても Number とは IEEE 754 double であり、それしかない世界である
- Excel から計算の移植は楽勝だと思ったが、小数絡んだ計算をするととたんに大変になる
- 単純な計算といっても小数の精度は調査すること
- 大変じゃなくなるようなライブラリをちゃんと知っておくこと
- LibreOffice と Microsoft Excel では日付計算周りが値が違うことがある
- OneDrive でちゃんと確認せよ
- これも日付計算ライブラリをちゃんと知っておくこと
Qiitaに書くべきだったかな?