coldfusion - JavaCast 慷慨地四舍五入

标签 coldfusion cfspreadsheet

我计算总和并将它们放入我使用 Coldfusion 中的 POI 库生成的 Excel 工作表中。由于 Java 库需要类型化变量,所以我总是调用 setCellValue( JavaCast( "float", myVar ) ).03 让我意识到舍入错误。比转换为 float 后已知的差异要大得多。

<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,该值非常接近我的值,至少小数后的第二个数字被正确舍入?

最佳答案

简答:

使用 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: The float data type is a single-precision 32-bit IEEE 754 floating point. ...

double: The double data type is a double-precision 64-bit IEEE 754 floating point. ...

因此this thread指出(强调我的):

It's not that you're actually getting extra precision - it's that the float didn't accurately represent the number you were aiming for originally. The double is representing the original float accurately; toString is showing the "extra" data which was already present. ... [When converted to a double, it] will have exactly the same value, but when you convert it to a string it will "trust" that it's accurate to a higher precision, so won't round off as early, and you'll see the "extra digits" which were already there, but hidden from you

这就是为什么“601761.66”和“601761.6875”似乎在转换为 float 时四舍五入为“601761.7”,但在转换为 double 时显示为预期。

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

关于coldfusion - JavaCast 慷慨地四舍五入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43323841/

相关文章:

coldfusion - 将单词 "and"附加到列表中的最后一个元素?

excel - cfSpreadsheet 2 位数年份

coldfusion - 使用 cfwheels、coldfusion 和 cfspreadsheet 创建具有非标准列名称(带空格)的 excel 文件导出

excel - 我可以调整 Excel 列的宽度而不单独设置它们吗?

javascript - 复杂的Javascript计算

hibernate - 如何在 Hibernate 中级联删除集合?

mysql - 类别和子类别的分组和输出

javascript - 创建更好的 JSON 格式

list - cfspreadsheet 在逗号分隔的行插入中转义逗号

coldfusion - 如何定义 cfspreadsheet 对象上的行数?