我计算总和并将它们放入我在Coldfusion中使用POI库生成的Excel工作表中。由于Java库需要类型变量,我总是调用setCellValue( JavaCast( "float", myVar ) )
。我被.03
意识到了舍入错误。比铸造漂浮后通常已知的差异更大的方式。
<cfset s = 601761.66>
<cfoutput>
#s#<br>
#JavaCast( "float", s )#<br>
#LSNumberFormat( JavaCast( "float", s ), ".0000000" )#<br><br>
</cfoutput>
601761.66
601761.7
601761,6875000
等于601761,69
,并且比我输入的值大.03
。我知道,LSNumberFormat
会返回一个字符串。我把它称之为比较。 POI似乎存储浮点值,Excel最终显示值为LSNumberFormat。
如何将一个值传递给setCellValue
,这个值非常接近我的值,至少在decmal之后的第二个数字被正确舍入?
答案 0 :(得分:4)
简答:
使用double类型而不是float,即javacast("double", value)
更长的回答:
Cell.setCellValue()方法实际上需要类型Double(不是Float)。 Double也是CF用于most numeric operations and functions的内容。将Float传递给这些方法时,它会隐式转换为Double。该转换(间接)导致意外结果。
原因是Float and Double are approximate types。但是,Double具有更高的精度:
float :浮点数据类型是单精度32位IEEE 754浮点。 ......
double :双数据类型是双精度64位IEEE 754浮点。 ...
正如this thread指出的那样(强调我的):
并不是说你实际上得到了更高的精确度 - 它是 浮动并没有准确地代表你的目标数量 本来。双精度表示原始浮子; toString显示&#34;额外&#34;已存在的数据。 ... [当转换为double时,它将具有完全相同的值,但是当您将其转换为字符串时,它将&#34;信任&#34;它准确到更高的精度,所以很早就会圆满结束,你会看到&#34;额外数字&#34;哪些已经存在,但对你隐藏
这就是为什么&#34; 601761.66&#34;和&#34; 601761.6875&#34; 似乎四舍五入到&#34; 601761.7&#34;当转换为浮动时,但在转换为双精度时显示。
<cfscript>
value1 = "601761.66";
value2 = "601761.6875";
WriteOutput("<br>[Float] "& value1 &" = "& javacast("float", value1));
WriteOutput("<br>[Float] "& value2 &" = "& javacast("float", value2));
WriteOutput("<br>[Float=>Double] "& value1 &" = "& javacast("double", javacast("float", value1)));
WriteOutput("<br>[Double] "& value1 &" = "& javacast("double", value1));
WriteOutput("<br>[Double] "& value2 &" = "& javacast("double", value2));
</cfscript>
<强>输出:强>
[Float] 601761.66 = 601761.7
[Float] 601761.6875 = 601761.7
[Float=>Double] 601761.66 = 601761.6875
[Double] 601761.66 = 601761.66
[Double] 601761.6875 = 601761.6875
NB: CF使用Float.toString()和Double.ToString()通过cfoutput / writeOutput / cfdump显示值。