MathFloor()関数のバグか?
くるくるワイドのEAで、なぜかトラップ本数がおかしいケースがあって調べていました。
本体7万通貨に対して、トラップのロットが5000通貨の時、トラップ本数は…
0.7 ÷ 0.05 で14本となるはずですよね。
なのにEAで処理すると13本になる。
この計算は割り算の商の整数部分のみを使うので、小数点以下を切り捨てる
MathFloor() という関数を使っていて
MathFloor(0.7/0.05);
という式になります。
どう考えてもきっちり割り切れるし、少数なんて無いんだから 14になるはずだろ。
バグじゃねーかよ(‘Д’)
と 他人のせいにしてしまいました。
浮動小数点数の MathFloor() は注意が必要
でも、よくよく調べてみると
小数点の処理に使っている浮動小数点数というのは誤差が発生するようで、この誤差が影響して変な結果に繋がっていたようです。
小数点以下の値については2のべき乗で割り切れない値については循環小数が発生し必ず誤差が発生し、2のべき乗で割り切れる値の組み合わせでは誤差は発生しないようです。
調べた結果、今回の計算は、内部的に
0.69999999999999991 / 0.050000000000000003 = 13.999999999999998
と処理されているようで、
13.999999999999998の少数点以下を切り捨てて 13となってしまうようです。
なので、処理としては正常で、自分の組み方が悪かったのです(・_・;)
対策
対策として両辺に100を掛けて、分子と分母を整数にした後に処理するようにしたらうまくいきました。
MathFloor((0.7*100)/(0.05*100));
レアなケースかな?と思ったので情報共有してみました。
あと、おそらく 切り上げ関数の MathCeil() も同じかと思います。
参考になれば幸いです。
コメント