ColdFusion 2018から、変数作成時にデータ型が保持されるようになったが、計算式などに変数を代入すると自動でキャストされる。
例えば、下記のプログラムを実施すると
<cfset a=1> <cfset b="2"> <cfset c=a+b> <cfscript> for (key in Variables) { writeOutput("#key# = #Variables[key]#(#getMetadata(Variables[key])#) <br>"); } </cfscript>
ColdFusion 2016までは、変数 a も b も内部で文字列型で管理されていた。計算式を使用した c はDouble 型に変換されている。
A = 1(class java.lang.String)
B = 2(class java.lang.String)
C = 3(class java.lang.Double)
データ型が保持されるColdFusion 2021や2018では、変数 a は数字、b は文字列型で管理される。計算式を使用した c は変わらずDouble 型に変換されている。
A = 1(class java.lang.Integer)
B = 2(class java.lang.String)
C = 3(class java.lang.Double)
このように、ColdFusionでは引き続き処理に応じて必要な型に自動でキャストされるので、変数の型に意識することは少ないが、小数点を含む計算式では注意しないといけない場合がある。 例えば、一見して問題が無いような下記の計算でも、小数点の丸め誤差などで結果が異なってしまう場合がある。
<cfoutput> #1000001.234567-1000000#<br> #1000000.1234567-1000000#<br> #100 * 0.57# と #Int(100 * 0.57)#<br> </cfoutput>
1.23456699995 // 1.234567 じゃない
0.123456700006 // 0.1234567 じゃない
57 と 56
普段あまり遭遇しないので意識しないことも多い。でも、ふとした時に引っかかってしまう場合がある。その時はこの関数を使うことを覚えておこう。
<cfoutput> #PrecisionEvaluate(1000001.234567-1000000)#<br> #PrecisionEvaluate(1000000.1234567-1000000)#<br> #PrecisionEvaluate(100 * 0.57)# と #Int(PrecisionEvaluate(100 * 0.57))#<br> </cfoutput>
1.234567
0.1234567
57.00 と 57
その他・参考情報
PrecisionEvaluateを使用した結果が指数で表示された場合は、java.math.BigDecimalオブジェクトのtoPlainStringメソッドを使用すると良い