- PR -

POIについて

投稿者投稿内容
ヒロピン
常連さん
会議室デビュー日: 2003/12/14
投稿数: 35
投稿日時: 2006-04-28 15:47
数式のセル(例えばA1*100)をgetNumericCellValue()で取得すると
EXCEL上で計算された A1*100 ではなく、計算前の A1*100 を取得するのでしょうか?

セルA1が4.6だと無限小数になってしまいます・・・

セルA1が4.8だと480が取得できるので、
2進数の変換は関係なさそうだし、
理解できません。

ご教授お願いします。
ヒロピン
常連さん
会議室デビュー日: 2003/12/14
投稿数: 35
投稿日時: 2006-04-28 18:33
この現象と何か関係があるでしょうか?

訳せる方お願いします。

POI is only a file format reader/writer, not a functional equivalent
for excel.
Thus, it only writes formulas in a format excel understands, and does not
calculate formula results.

> I'm facing a weird problem: when I use the POI method
> getNumericCellValue() to read a formula cell in a sheet created by
> Excel, it returns me the formula result correctly. But when I use the
> same method to read a formula cell in a sheet created by POI, it
> returns me always the number zero. Can anyone tell me why? How can I
> get the formula result from a cell in a sheet created by POI?
> --=20
> Alessandro
Edosson
ぬし
会議室デビュー日: 2004/04/30
投稿数: 675
投稿日時: 2006-04-28 18:44
ここまでロコツなのも珍しいな・・・。
辞書を引けばすむくらいのこと、自分でやれば?
ヒロピン
常連さん
会議室デビュー日: 2003/12/14
投稿数: 35
投稿日時: 2006-04-28 18:59
翻訳はしてみたのですが関連性があるのかどうかまでは
解釈できませんでした・・・。

POIのバグでしょうか?

ご存知の方ご教授お願い致します。
かつのり
ぬし
会議室デビュー日: 2004/03/18
投稿数: 2015
お住まい・勤務地: 札幌
投稿日時: 2006-04-29 00:51
POIはExcelに書いてある式をそのまま内部のパーサで処理しています。
深い知識があって言っているわけではないですが、
逆コンパイルでわかりました。
単純に式をPOIが独自で評価しているものと思います。

純粋に考えると、Excelファイルには式しか書いてありません。
それを評価結果として受け取るにはExcelを起動するしかありません。
VBAやVBScriptでExcelを起動して値を取得する場合は、そのケースに該当しますね。
POIの場合、単純にExcelファイルを評価するだけです。

従って、スレ主の質問のケースで考えると、
式のセルの評価結果が循環小数になっている以上、
4.6D * 100.0DをJavaで評価しているものとしか考えられません。

つまり、Excelで評価しているわけではなく、
POIで評価している以上、4.6D * 100.0Dの結果である循環小数になるのは
当然のものであり、POIのバグではありません。

広く使われているライブラリのバグを疑うよりも、
仕様の確認や、自分の考えの合理性を疑いましょう。
循環小数になる以上、double型で計算されているわけです。
2進数によるdoule型の表現の問題が関係しています。
ヒロピン
常連さん
会議室デビュー日: 2003/12/14
投稿数: 35
投稿日時: 2006-05-02 10:20
かつのりさんお返事ありがとうございます。

もう少し自分で調査してみます。
ヒロピン
常連さん
会議室デビュー日: 2003/12/14
投稿数: 35
投稿日時: 2006-05-02 17:02
規則性が分かりません・・・。

System.out.println("【4.1】" + 4.1d * 100d);
System.out.println("【4.2】" + 4.2d * 100d);
System.out.println("【4.3】" + 4.3d * 100d);
System.out.println("【4.4】" + 4.4d * 100d);
System.out.println("【4.5】" + 4.5d * 100d);
System.out.println("【4.6】" + 4.6d * 100d);
System.out.println("【4.7】" + 4.7d * 100d);
System.out.println("【4.8】" + 4.8d * 100d);
System.out.println("【4.9】" + 4.9d * 100d);
System.out.println("【5.0】" + 5.0d * 100d);

上記のコードを実行すると

【4.1】409.99999999999994
【4.2】420.0
【4.3】430.0
【4.4】440.00000000000006
【4.5】450.0
【4.6】459.99999999999994
【4.7】470.0
【4.8】480.0
【4.9】490.00000000000006
【5.0】500.0

となります。

自分は二進数で表現できない小数だけが無限小数になるものだと思い込んでいました。
しかし、上記の結果を見ると二進数で表現できない小数が有限小数になっています。
普段はBigDecimalを使用しているのでdoubleについては詳しくありません。
doubleは内部でどのような処理がされているのでしょうか。
ご存知の方ご教授お願いします。
ヒロピン
常連さん
会議室デビュー日: 2003/12/14
投稿数: 35
投稿日時: 2006-05-11 17:28
2進数で表すと以下のようになります。

【4.1】100.0001100110011001100110011001100110011001100110011
【4.2】100.00110011001100110011001100110011001100110011001101
【4.3】100.01001100110011001100110011001100110011001100110011
【4.4】100.0110011001100110011001100110011001100110011001101
【4.5】100.1
【4.6】100.1001100110011001100110011001100110011001100110011
【4.7】100.10110011001100110011001100110011001100110011001101
【4.8】100.11001100110011001100110011001100110011001100110011
【4.9】100.1110011001100110011001100110011001100110011001101
【5.0】101.0

どのように丸め処理がされているのでしょうか。
Javaのdouble型の誤差について詳しい説明が載っているサイトを
ご存知でしたら教えてください。
よろしくお願いします。

スキルアップ/キャリアアップ(JOB@IT)