2017-04-10 16 views
3

私は合計を計算し、これらをExcelシートに入れて、ColdFusionでPOIライブラリを使用して生成します。 Javaライブラリは型付きバールを期待しているので、私はいつもsetCellValue(JavaCast("float", myVar))を呼び出します。私は.03で丸め誤差を認識しました。浮遊するように鋳造した後に典型的に知られている違いよりも大きい。JavaCast float round generous

<cfset s = 601761.66> 
<cfoutput> 
#s#<br> 
#JavaCast("float", s)#<br> 
#LSNumberFormat(JavaCast("float", s), ".0000000")#<br><br> 
</cfoutput> 
  • 最初の行が印刷601761.7
  • から
  • 第二ラウンド601761.66第しかしながらプリント:601761,69に、私は中に入れた値よりも大きい.03によって等しい601761,6875000

私が知っているとおり、LSNumberFormatは文字列を返します。私はそれを単に比較のために呼びました。 POIは浮動小数点値を格納しているようですが、最終的にExcelはLSNumberFormatの値を表示します。

setCellValueに値を渡すと、私の値に非常に近いので、少なくとも小数点以下の2桁目が正しく丸められますか?

+0

なぜ、NumberFormの代わりに 'LSNumberFormat'を使用しますか?で? –

+1

おそらく、NumberFormatは米国の書式設定ルールのみをサポートしているからです。 – Leigh

+0

この場合、LSNumberformatを使用して3桁以上の10進数を表示します。実際のアプリケーションでは、この関数を使ってドットの代わりにカンマを小数点区切りとして取得します。 –

答えて

4

短い答え:代わりにフロートの二重

使用タイプ、すなわちjavacast("double", value)

長い答え:Cell.setCellValue()方法は実際Double(ないFloat)型期待

。ダブルはまた、CFがmost numeric operations and functionsに使用するものです。これらのメソッドにFloatを渡すと、暗黙的にDoubleに変換されます。その変換は(間接的に)予期しない結果を引き起こします。その理由は、両方ともFloat and Double are approximate typesであるためです。

フロート:ただし、ダブルより高い精度を有する浮動小数点データ型は、単精度32ビットIEEE 754浮動小数点です。 ...

doubleダブルデータ型は、倍精度の64ビットIEEE 754浮動小数点型です。 ... this threadよう

が指摘する(強調鉱山):

それはあなたが実際に余分な精度を取得していることではない - それは フロートは正確にあなたがいた番号を表していなかったということですもともとは を目指していました。ダブルは元のフロートを正確に表しています。 toStringは、既に存在していた「余分な」データを示しています。 ... [ダブルに変換すると、それは]正確に同じ値を持ちますが、文字列に変換すると、精度がより正確であることを「信頼する」ので、は早期に四捨五入されません既に存在していたが、あなたには隠されていた「余分な数字」が表示されます。

その理由は、両方とも「601761」です。66" と "601761.6875 doubleとしてキャストすると予想されるfloatとしてキャストするとき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は、cfoutput/writeOutput/cfdumpを使用して値を表示するためにFloat.toString()とDouble.ToString()を使用します。