2017-04-10 46 views
3

我計算總和,並把它們放入我在Coldfusion中使用POI庫生成的Excel工作表中。由於Java庫期望輸入變量,我總是調用setCellValue(JavaCast("float", myVar))。我被告知.03四捨五入的錯誤。比鑄造浮動後通常已知的差異更大。JavaCast 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與我的值非常接近以至於十進制後的第二位數字被正確舍入?

+0

爲什麼要使用'LSNumberFormat'而不是'NumberForm at'? –

+1

可能是因爲NumberFormat僅支持美式格式規則。 – Leigh

+0

在這種情況下,我只使用LSNumberformat來查看兩位以上的小數位。在現實生活中,我使用這個函數來獲得逗號而不是點。 –

回答

4

短的答案:

使用型雙代替浮子,即javacast("double", value)

較長答案:

Cell.setCellValue()方法實際上預計鍵入Double(未Float)。 Double也是CF使用的most numeric operations and functions。當您將Float傳遞到這些方法時,它會隱式轉換爲Double。該轉換(間接)導致了意外的結果。

原因是這兩個Float and Double are approximate types。然而,雙具有更高的精確度:

浮子:浮子數據類型是單精度32位IEEE 754浮點。 ...

double:雙數據類型是一個雙精度64位IEEE 754浮點。 ...

因此,作爲this thread指出(重點煤礦):

這並不是說你實際上得到額外的精度 - 這是該 浮動並不能準確地代表你是多少最初瞄準 。雙精度表示原始的浮點數; toString顯示已經存在的「額外」數據。 ... [當轉換爲double時,它將具有完全相同的值,但是當您將其轉換爲字符串時,它會「信任」它準確到更高的精度,因此不會像,你會看到它已經在那裏了「額外數字」,但是從你

隱藏這就是爲什麼這兩個「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 

NB: CF使用Float.toString()和Double.ToString()通過cfoutput/writeOutput/cfdump顯示值。