JavaCast 浮点数大方
Posted
技术标签:
【中文标题】JavaCast 浮点数大方【英文标题】:JavaCast float rounds generously 【发布时间】:2017-04-10 12:59:16 【问题描述】:我计算总和并将它们放入我使用 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
,该值与我的值非常接近,至少小数点后的第二个数字被正确舍入?
【问题讨论】:
为什么要使用LSNumberFormat
而不是NumberFormat
?
可能是因为 NumberFormat 只支持美国格式规则。
在这种情况下,我使用 LSNumberformat 只是为了查看两个以上的十进制数字。在现实生活中的应用程序中,我使用此函数将逗号作为小数分隔符而不是点。
【参考方案1】:
简答:
使用 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:float 数据类型是单精度 32 位 IEEE 754 浮点数。 ...
double:double 数据类型是双精度 64 位 IEEE 754 浮点数。 ...
正如this thread 指出的那样(强调我的):
这并不是说您实际上获得了额外的精度 - 而是 float 不能准确地代表您的目标数字 起初。双精度表示原始浮点数; toString 显示已经存在的“额外”数据。 ... [当转换为双精度时,它] 将具有完全相同的值,但是当您将其转换为字符串时,它会“相信”它的精确度更高,因此 不会四舍五入为早,您会看到已经存在但对您隐藏的“额外数字”
这就是为什么“601761.66”和“601761.6875”似乎在转换为浮点数时都被舍入为“601761.7”,但在转换为双精度时却显示为预期。
<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
注意: CF 使用 Float.toString() 和 Double.ToString() 通过 cfoutput/writeOutput/cfdump 显示值。
【讨论】:
以上是关于JavaCast 浮点数大方的主要内容,如果未能解决你的问题,请参考以下文章