• ベストアンサー

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になってしまいます。 これはいったいどういうことなのでしょうか。 値が減ることなんてありえるのでしょうか? よろしくお願いします。

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

  • ベストアンサー
noname#11476
noname#11476
回答No.1

こういう場合真っ先に疑うのは「桁落ち」です。 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に対する計算のどこかでわずかに計算結果の異なるライブラリなどが使われているためではないでしょうか。

youking
質問者

お礼

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

その他の回答 (2)

  • yotta
  • ベストアンサー率32% (26/79)
回答No.3

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

youking
質問者

お礼

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

  • drmoreau
  • ベストアンサー率41% (33/79)
回答No.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言語は文法的なエラーがあっても一応動きますので、バグに気づきにくいのです。ただその出力結果は不安定になります。

youking
質問者

お礼

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

youking
質問者

補足

すいません、 printf("%s %lf,%d",mes,test2,test1); は sprintf("%s %lf,%d",mes,test2,test1); の間違えでした。

関連するQ&A

  • unsigned int型について

    C言語初心者です。 unsigned int型に関する質問です。 --------------------------------- #include <stdio.h> int main(void) { unsigned int in1 = 10; unsigned int in2 = -10; unsigned char ch1 = 10; unsigned char ch2 = -10; printf("in1 = %d\n", i); printf("in2 = %d\n", i); printf("ch1 = %d\n", ch1); printf("ch2 = %d\n", ch2); return 0; } --------------------------------- 上記のプログラムを作成して実行すると、結果は以下の通りです。 [実行結果] in1 = 10; in2 = -10; ch1 = 10; ch2 = 246; 変数in2の値を表示した結果に関してですが、 unsigned int型にも関わらず負の値「-10」が表示されるのは 何故でしょうか?

  • int→unsigned int キャスト

    int test01; unsigned test02; の場合、test02にtest01の値を代入したい場合どうすればよいでしょうか? 型は変更できません。 キャストして代入しても大丈夫でしょうか?

  • int型とchar型について

    C言語初心者です。 よろしくお願いします。 ◎1----------------------- #include<stdio.h> int main(void) { int ss[4]="789"; printf("%c\n",ss[0]); return 0; } --------------------------- ◎2----------------------- #include<stdio.h> int main(void) { int *p; p="789"; printf("%c\n",*p); return 0; } --------------------------- ◎1、◎2の2つのプログラムについて疑問があります。 ◎1の「int ss[4]="789";」と◎2の「int *p;」のintの部分は今まで、何の疑問も抱かず、「char」として入力していました。 そこでchar型は1バイトの整数、int型は4バイトの整数ということで容量が違うだけで、intとしても大丈夫だろうと思ったのですが、 ◎1では、「'initializing' : 'char [4]' から 'int [4]' に変換することはできません。」とエラーが出て、◎2では「'char [4]' から 'int *' に変換することはできません。」とエラーが出ます。 intは文字列は扱えないということなのでしょうか? 以上intだと実行できない理由がわかりません。 初歩的なことですいませんが、教えていただけると嬉しいです。

  • char型+char型ってint型? if(char型==int型)?

    C言語の「汎整数拡張(インテグラルプロモーション)」というものに関するものだと思います。 char型とchar型を加えた結果は、char型でしょうか。それともint型でしょうか。 (下のプログラムの printf("sizeof(a[0]+a[1])は%d\n", sizeof(a[0]+a[1])); /* char型+char型 */ という部分の結果は4なので、int型と考えるべきなのかな。) 私は、char型とint型の加算の結果はint型だと思っていましたが、 char型とchar型の加算の結果はやはりchar型だと思っていました。 (それが間違えているのでしょうか。) if(a[0]==i) /* char型とint型の比較(?) */ の部分では、左辺はchar型、右辺はint型ですが、このように型の違う変数を比較しても文法上構わないのでしょうか。 (私は、「比較は必ず型の同じもの同士でしかできない」と思っていました。) 左辺はchar型のように見えて、じつはint型ですか。 #include <stdio.h> int main(void) { char a[4]; int i=77; printf("sizeof(int)は%d\n", sizeof(int)); printf("sizeof(char)は%d\n", sizeof(char)); printf("sizeof('M')は%d\n", sizeof('M')); printf("sizeof(a[0])は%d\n", sizeof(a[0])); a[0]='M'; a[1]=7+6; a[2]=a[0]+a[1]; printf("sizeof(a[0]+a[1])は%d\n", sizeof(a[0]+a[1])); /* char型+char型 */ printf("sizeof(+a[0])=%d\n", sizeof(+a[0])); if(a[0]==i) /* char型とint型の比較(?) */ puts("a[0]==i"); else puts("a[0]!=i"); return(0); } ちなみにワーニングもエラーもなんにもでません。

  • c言語でint配列をdoubleに変換

    c言語でマイコンプログラムを作成しています. int型の配列をdoubleに変換するために以下のプログラムを記述し,テストしました. int a[4] = {0,0,1,8}; char s[4]; double d; char *temp; sprintf(s,"%d%d%d%d",a[0],a[1],a[2],a[3]); //文字列charをdoubleに変換 d = strtod(s,&temp); 望む結果は 18 ですが,なぜか上記結果は 1800 となりました. 試しに int a[4] = {1,2,3,4}; と,1234と表示されました. 上記より,出力値が左詰めのようになっています. 試しにVisual Studio 2013 C++で同様のプログラムを実行すると,所望の結果を得ることが出来ました. プログラムがおかしいのでしょうか?それともマイコンのコンパイラのバグでしょうか? お分かりになられる方がいらっしゃいましたら,ご教授宜しくお願い致します.

  • C言語のint型の配列が分かりません

    #include<stdio.h> int main(void) { int str[ ]={0,1,2} printf("%s\n", str); return 0; } というプログラムをC言語でつくってみましたが動きません.(012と表示されて欲しかったのですが) int str[ ]={1,2,3}の部分をchar str[ ]={'0','1','2'}とすれば動きます. そこで質問なのですが, printf("~%s~", (配列名));  はchar型の配列にしか適応できないのですか? ※追記 puts関数の定義は int puts (const char *str); であるそうなので char型の仮引数にはchar型のアドレスを渡さなければいけません. ではprintf関数の定義は一体どんなものなのですか?

  • double型の値を、一桁ずつint型に格納したい

    こんばんは。 タイトルの通り、double型の値を、一桁ずつint型に格納したいのです。 例えば、 double kazu = 123.4 を、 int kurai100 = 1 int kurai10 = 2 int kurai1 = 3 int kurai01 = 4 double kazu = 12.3 を、 int kurai100 = 0 int kurai10 = 1 int kurai1 = 2 int kurai01 = 3 のように格納する関数が欲しいのですが、 どういうふうにやるのが妥当でしょうか。 なんとなく、いったんchar型の配列に変換して、 int型に入れる感じになりそうだとは思うのですが、 double型からchar型にうつす方法がわからないのと、 必ずしも100の位まででなくて、 10の位までしかない場合もあるので、そういう場合、 Char型の配列の添え字がずれるのではと、 悩んでいます。 void henkan(double kazu, &int kurai100, &int kurai10, &int kurai1, &int kurai01) こういう関数があるといいのですが、どういうふうになるのでしょうか。 使わなかった位には0が入ればいいのですが。 よろしくおねがいします。

  • C言語でコマンドラインの引数について。

    コマンドラインで引数をわたす基本的なプログラムは main(int argc,char *argv[]){....] ですよね。 今回実行時に、 >実行ファイル名 123 + 233 といれたら、123+233を計算してくれるプログラムを作ろうとしています。 その場合、main(int argc,int *argv[]){} としたら、argv[1]に123が入って、argv[2]に+が入って、argv[3]に233が、入るというわけではないんでしょうか? とりあえず、確認で #include<stdio.h> main(int argc,int *argv[]) { printf("%d\n%d\n",argv[1],argv[3]); } としてみたんですが、実行結果は、とても長い数字がでてきてきました。 なにがいけないのか教えてください。 お願いします。 あとWindows MEでVC++6を使ってます。

  • int型の表せる範囲

    VC++6.0 on win2kです。 int型の表せる範囲は3万ぐらいまでだと思っていたのですが、 #include <stdio.h> #define Max 1000000 void main(){ for(int i=0;i<Max;i++){ printf("%d\n",i); } } というプログラムを走らせると普通に出ます。 int型の範囲とは何を意味するのでしょうか?

  • intとlongは同じ?

    #include <stdio.h> #include <limits.h> int main() { printf("%d\n%d", INT_MAX, LONG_MAX); return 0; } 出力 214783647 214783647 Win7 64bit (VC++2010) CentOS 32bit (gcc) どちらの環境でも同じ出力結果となりました。 intとlongなぜ同じになってしまったのでしょうか。

専門家に質問してみよう