JavaCast浮动慷慨地

时间:2017-04-10 12:59:16

标签: coldfusion cfspreadsheet

我计算总和并将它们放入我在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之后的第二个数字被正确舍入?

1 个答案:

答案 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显示值。