本件につきまして、追加のご連絡となります。
動作を色々と試していたところ、INTやTRUNC関数に限らず、おかしな出力となっているようでした。
自動項目で下記のような設定を行い、出力した結果を記載いたします。
【自動項目1】
[金額]
INT(100 * 1.15)
=114.000
[数量]
500
[合計]
57,000.000
【自動項目2】
[金額]
100 * 1.15
=115.000
[数量]
500
[合計]
57,499.999
以上となります。
この現象につきましてご確認いただけますと幸いです。
よろしくお願いいたします。
@kyosuketanaka
回答するのが難しくて遅くなりました。
結論から言うと、今のところ仕様ということになります。議論の余地はあるかと思っています。
■AFormsにおける計算の方法について
計算で誤差が生じる原因ですが、これは一般的な小数点演算ではよくあることです。
Excelなんかも同じで、1.2 – 1.1が0.1ではなく0.99999999だったりします(9がいくつ続くかは環境によって違うはずです)。
この演算方法はIEEE754という規格に基づくものですが、デファクトスタンダードになっていて、ブラウザ上であろうがサーバー上であろうが基本的にはこの演算方法で計算が行われます。
それとはまた別の話で、金額の計算で誤差が生じては困るので、ECシステムやら会計システムでは別の方法で計算していることもあります。
ただし、金額の計算では「べき乗」のような高度な計算は不要なので、そもそも使えない場合もあります。
AFormsでは、数式を使った場合はIEEE754に従って計算が行われます。
また、明細行の金額(単価×数量)の計算では、その計算をした後に端数処理(フォーム設定で設定できるもの)を行うことで、誤差を適宜補正できるようにしてあります。
ユーザー視点の意見として、AFormsにおける計算で「べき乗」などの高度な計算ができる必要があるのか、そのために誤差が生じるのはどうなのか、というのはあるかなと思います。
難しいところです。
■kyosuketanakaのケースで何が起こっているか(10月4日の書き込みについて)
【自動項目1】では、”100 * 1.15″の結果が114.99999などになり、INT()で切り捨てられて単価が114.000になっています。
【自動項目2】も、”100 * 1.15″の結果が114.99999などになり、そのため明細行の金額は114.999999×500≒57,499.99999が端数処理された57,499.999になっています。
単価の表示が”115.000″になるのは、114.999999を表示のためにフォーマットした結果です。
大変丁寧にご回答いただきまして誠にありがとうございます。
浮動小数点の計算上における端数処理での誤差ということですね。
あまり小数点を扱うプログラムを扱ってこなかったため気づきませんでした。
いわれてみれば納得です。
適切にROUND関数で整えていく必要があるようですね。
@kyosuketanaka
適切にROUND関数で整えていく必要があるようですね。
そうですね。
他には、あらかじめ100倍しておいて、すべて整数で計算するようにする方法もあります。