小数点での計算を行う場合、特に金額等を計算する場合に丸め誤差を回避する手段としてPrecisionEvaluate関数が用意されています。ColdFusionのオンラインマニュアルの「データ型開発ガイド」にも下記のような説明がされています。
(抜粋)
ColdFusion には、任意の長さの 10 進数(1234567890987564.234678503059281 など)を表す特殊な BigDecimal データ型は用意されていません。このような数値は文字列として表現されます。ただし、BigDecimal 値を含む数式を受け取って計算し、結果の BigDecimal 値を文字列で返すことができる PrecisionEvaluate 関数があります。詳細については、『CFML リファレンス』の PrecisionEvaluate を参照してください。
ただ、PrecisionEvaluate関数を使用して画面に値を表示した際に、値が指数表示になる場合があります。
(例)
<cfoutput>#PrecisionEvaluate(0.00000123)#</cfoutput>→0.00000123
<cfoutput>#PrecisionEvaluate(0.000000123)#</cfoutput>→1.23E-7
PrecisionEvaluate関数の値に数値を指定した際の戻り値は、java.math.BigDecimalオブジェクト
です。本来、ColdFusionでは、<cfoutput>はオブジェクトをそのまま画面に表示できませんが、今回のjava.math.BigDecimalオブジェクトにはtoStringメソッドが含まれているため、内部でtoStringを実行して文字列に変換したものを画面に表示しています。そこでJavaのドキュメント(→参考リンク)で、toString メソッドの動作を確認すると、“指数が必要な場合、科学表記法で、このBigDecimalの文字列表現を返します”と記載されています。
(抜粋)
BigDecimal
の正規の文字列形式は、次の手順で作成されます。まず、BigDecimal
のスケールなしの値の絶対値が、「0
」から「9
」までの文字を使用した、先頭に0が付かない文字列(基数10)に変換されます(ただし、値が0である場合は、単一の文字「0
」が使用される)。次に、調整された指数が計算されます。これは、正負を逆にしたスケールに、変換されたスケールなしの値の文字数を加算したものから1を減算したものです。つまり、
-scale+(ulength-1)
であり、ulength
は10進数のスケールなしの値の絶対値の長さ(精度)です。スケールが0以上で、調整された指数が
-6
以上である場合、数値は指数表現なしの文字形式に変換されます。この場合、スケールが0のときは小数点は追加されません。スケールが正のときは、小数点がスケールとともに挿入され、小数点以下の文字数が指定されます。必要に応じて、変換されたスケールなしの値の左に文字「0
」が追加されます。この挿入のあとに小数点に先行する文字がない場合は、先頭に通常の文字「0
」が付けられます。その他の場合(つまり、スケールが負、または調整された指数が
-6
未満の場合)、数値は指数表現を使用して文字形式に変換されます。この場合…(以下略)先ほどの例ですと、どちらも絶対値は123ですが、スケールが前者が 8 で後者が 9、それで正負を逆にしたスケールに変換されたスケールなしの値の文字数(123→3)から1を減算したものとして、前者は -8+(3-1)=-6、後者は -9+(3-1)=-7が調整された指数となります。
上記のPrecisionEvaluate(0.000000123)は、調整された指数が-7であるため指数表現を使用した文字形式に変換されていることが分かりました。
では、指数表現による文字列形式の表示を回避する方法としては、java.math.BigDecimalオブジェクトのtoPlainStringメソッドを呼び出して、指数表現をしない文字列に変換したものを表示するという方法があります。先ほども紹介したJavaのドキュメント(→参考リンク)にtoPlainStringに関しても記載がございますので、詳細はそちらを確認ください。
【例】
<cfoutput>#PrecisionEvaluate(0.00000123).toPlainString()#</cfoutput>→0.00000123
<cfoutput>#PrecisionEvaluate(0.000000123).toPlainString()#</cfoutput>→0.000000123
記事公開日:2020年07月06日
最終更新日:2020年07月14日
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Praesent suscipit iaculis libero sed tristique. Quisque mollis dolor non tellus placerat vitae sodales lectus porta. Curabitur ut suscipit tellus. Maecenas rhoncus, ante vitae vehicula vestibulum, metus sapien dapibus tellus, et mattis dolor neque vitae nisl. Nullam eleifend ultrices ipsum eget pretium. Curabitur semper metus ut ante adipiscing nec volutpat sem rutrum. Nullam a nisi lacus, non interdum ante. Vivamus ante augue, commodo vel egestas sed, pharetra nec dui. Quisque sed tellus felis. Donec ipsum mauris, sagittis eu accumsan in, aliquam non ipsum.
Vestibulum tempor nunc nec felis scelerisque eget elementum erat dignissim. Ut vel ipsum mollis orci venenatis luctus. Aenean vehicula quam vel quam porttitor ac iaculis elit pulvinar. Proin consequat, ipsum eu venenatis semper, justo turpis posuere tortor, ac placerat metus nisl et lectus. Nulla cursus dui id nunc ullamcorper sed semper nisl lobortis. Aliquam erat volutpat. Phasellus arcu ante, imperdiet in ornare sed, laoreet eu massa.