こんにちはゲストさん。会員登録(無料)して質問・回答してみよう!

解決済みの質問

doubleからintへのキャスト

場合によって値が変わってしまいます。
これはいったいどういうことでしょうか??
開発環境はWindows2000 VC++6.0
実行環境はWindows98です。
Windows2000で実行した場合は値は一緒なのですが
Windows98の場合は値が変わってしまいます。
Windows98で下のプログラムを実行すると

int test1;
double test2;



test1 = (int)test2
char mes[1024];
printf(mes, "%lf, %d", test2, test1);

test2は100.000000
そしてtest1が100となります。
しかし、プログラム実行中にプログラムメニューの[印刷]等、Windowsのメニューを使うと
test2は100.000000なのですが
test1が99になってしまいます。

これはいったいどういうことなのでしょうか。
値が減ることなんてありえるのでしょうか?
よろしくお願いします。

投稿日時 - 2002-10-25 11:19:40

QNo.389367

すぐに回答ほしいです

質問者が選んだベストアンサー

こういう場合真っ先に疑うのは「桁落ち」です。
test2 は見かけ上は 100.000000 でも、実際には、
99.99999999999999
ということもありえます。
そうするとこのintを取ると、test1 = (int) test2 とすると test1 = 99 になります。
つまり切り捨てになっているわけです。

たとえば、
test1 = (int) ( test2 + 0.5 )
とすると、test2を小数点以下四捨五入したことになります。

確かめるのは、たとえば test1 = (int) (test2 + 0.0000001) と小さい数字を加算してどうなるかを確かめて見ましょう。

Win2000とWin98で動作が異なるのはおそらく、test2に対する計算のどこかでわずかに計算結果の異なるライブラリなどが使われているためではないでしょうか。

投稿日時 - 2002-10-25 11:31:56

お礼

そう言う現象があるのですか。
ありがとうございます。
早速、試してみます。

投稿日時 - 2002-10-25 13:14:48

このQ&Aは役に立ちましたか?

1人が「このQ&Aが役に立った」と投票しています

回答(3)

ANo.3

int型は,16ビットマシン(Windows98)では,16ビット(2バイト)になります.
32ビットマシン(Windows2000)では,32ビット(4バイト)になります.
従って,int型は使わず,short型:16ビット(2バイト)かlong型:32ビット(4バイト)の指定をお勧めします.

投稿日時 - 2002-10-25 12:35:16

お礼

そういう根本的なところに問題があったのですか。
試してみます。
ありがとうございました。

投稿日時 - 2002-10-25 13:13:17

ANo.2

プログラムすべてを書かれていないのではっきりしたことはいえませんが、どこかで、test1にごみが入っているのではないですか。
キャストをすると精度が変わりますので、値が変わる場合がありますが、それは、doubleの変数に-32768以下か32767以上の数値を入れて、キャストしたような場合です。この場合数値が100ですので、数値がおかしいのは、他の部分に原因があると思います。
ちなみにprintf関数の使い方も間違っています。

printf(制御文字列,変数1,変数2,....);

このプログラムの場合、制御文字列にあたる部分が、mesと"%lf,%d"と二つあります。BASICとは違って、こういったミスに対して、シンタックスエラーの表示はされませんので、気をつけてください。

printf("%s %lf,%d",mes,test2,test1);

あるいは、

strcpy(mes,"何らかのメッセージ %lf,%d");
printf(mes,test2,test1);

が正しい書き方です。
c言語は文法的なエラーがあっても一応動きますので、バグに気づきにくいのです。ただその出力結果は不安定になります。

投稿日時 - 2002-10-25 12:04:31

補足

すいません、
printf("%s %lf,%d",mes,test2,test1);

sprintf("%s %lf,%d",mes,test2,test1);
の間違えでした。

投稿日時 - 2002-10-25 12:18:50

お礼

補足書き間違えました。
printf(mes, "%lf, %d", test2, test1);

sprintf(mes, "%lf, %d", test2, test1);
の間違えでした。すいません。以後気をつけます。

投稿日時 - 2002-10-25 12:25:47

あなたにオススメの質問