- PR -

時間を表示/バグについて

投稿者投稿内容
jack
常連さん
会議室デビュー日: 2002/07/24
投稿数: 22
投稿日時: 2002-07-24 04:26
時間を取得して、それをJavaアプリケーションに動的なコンポーネントとして貼り付けるにはどうしたらよいのですか?様々な書籍やページを見ましたが、ただ時間を表示するだけのアプリケーションや、実行を開始したときの時間を表示するプログラムしかなくて困っています。
あと、私はjdk1.3.1を使っているのですがバグを見つけました。例えば84 / 0.7が120.0ではなく120.00……01になってしまう。同じ事をC言語でやるとうまくいくのでJavaコンパイラの計算機ルーチンによるバグだと思われるのですが、このバグレポートは提出されているのでしょうか?
asip
ベテラン
会議室デビュー日: 2001/12/27
投稿数: 77
投稿日時: 2002-07-24 05:59
引用:

jackさんの書き込み (2002-07-24 04:26) より:
(中略)
あと、私はjdk1.3.1を使っているのですがバグを見つけました。例えば84 / 0.7が120.0ではなく120.00……01になってしまう。同じ事をC言語でやるとうまくいくのでJavaコンパイラの計算機ルーチンによるバグだと思われるのですが、このバグレポートは提出されているのでしょうか?



自分の勝手な思いこみでバグと判断するのはおかしいですよ。

はっきりいいます、それはバグではありません。

JAVA言語仕様は読んだのですか?
何を根拠にCと比較しているのですか?

CとJavaは"違う"言語ですよ。仕様の異なる部分があるのは当たり前です。

84/0.7の"84"と"0.7"の型は何ですか?

Javaではint/(doubleあるいはfloat)の場合、計算結果は"doubleあるいはfloat"
になります。

これを"型拡張"といいます。

1)どちらかのオペランドが"double"なら、もう一方も"double"に。
2)どちらかのオペランドが"float"なら、もう一方も"float"に。
3)どちらかのオペランドが"long"なら、もう一方も"long"に。
4)オペランドの双方が"int"なら、そのまま。

Javaの文法を解説した書籍には書いてあるはずですが...。
jack
常連さん
会議室デビュー日: 2002/07/24
投稿数: 22
投稿日時: 2002-07-24 12:17
返信ありがとうございます

>>Javaではint/(doubleあるいはfloat)の場合、計算結果は"doubleあるいはfloat"
>>になります。

>>これを"型拡張"といいます。

>>1)どちらかのオペランドが"double"なら、もう一方も"double"に。
>>2)どちらかのオペランドが"float"なら、もう一方も"float"に。
>>3)どちらかのオペランドが"long"なら、もう一方も"long"に。
>>4)オペランドの双方が"int"なら、そのまま。

これは当たり前のことですね。計算はint / doubleでしました。ここで84 / 0.7の場合、本来ならば120.0(120.00……00)になるはずです。これが120.00……01になってしまうのはれっきとしたバグだと思われるのですが、私が間違っているのでしょうか?
みやも
ベテラン
会議室デビュー日: 2002/04/22
投稿数: 74
投稿日時: 2002-07-24 13:00
宮本です。

>例えば84 / 0.7が120.0ではなく120.00……01になってしまう

本当だ。
84/(7*0.1)
84/7*0.1
微妙に値が変わってますね。


>Javaコンパイラの計算機ルーチンによるバグだと思われるのですが、このバグレポートは提出されているのでしょうか?

調べてみてください
http://developer.java.sun.com/developer/bugParade/

84/0.7で検索しても出てきませんでした。


これって何なんでしょうね?
言語に詳しい人、教えてくださいませ。
miki
大ベテラン
会議室デビュー日: 2001/09/21
投稿数: 174
お住まい・勤務地: 東京都八王子市
投稿日時: 2002-07-24 13:16
丸め誤差ですね。
http://gimlay.org/~javafaq/S029.html

私のgcc 2.96で実際に試してみました。
確かに、printf("%f", 84/0.7)を実行すると120.000000と表示されます。
でも、これは表示上小数点以下6桁で切っているだけだと思い、
次のようなプログラムを書いてみました。

#include "stdio.h"
int main() {
printf("%d\\n", 84/0.7 == 120.00000000000001);
printf("%d\\n", 84/0.7 == 120);
}

このプログラムの結果は、一行目は1、二行目は0になりました。
これを見る限り、Javaと計算結果は合っていると思います。



miki
大ベテラン
会議室デビュー日: 2001/09/21
投稿数: 174
お住まい・勤務地: 東京都八王子市
投稿日時: 2002-07-24 14:42
printのフォーマットの指定方法を忘れていました。
printf("%3.14f", 84/0.7)のように書けば望みの精度で表示されますね。
object
ぬし
会議室デビュー日: 2002/03/20
投稿数: 338
お住まい・勤務地: 香川県高松市
投稿日時: 2002-07-24 16:16
これは、丸め誤差と言うより、10進浮動小数を、IEEE 浮動小数点形式等の2進表現に、誤差なく完全には変換出来ないという、原理的な誤差だと思います。
従って、この誤差を避けたければ、2 進化 10 進数 (BCD: Binary Coded Decimal)を使うか、自分が必要な精度に、丸め処理をするかだと思います。
asip
ベテラン
会議室デビュー日: 2001/12/27
投稿数: 77
投稿日時: 2002-07-24 17:31
今朝の返答は的はずれでした..。

この問題は四則演算全てで起こり得ますね。

有効桁数を設定して、切り上げ・切り捨て・丸め等を考慮する必要があります。

演算時に分母を必ず整数になるようにする等、誤差を減らすロジックを考えるのも
有効だと思います。

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