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

解決済みの質問

型変換キャストについて

#include <stdio.h>
int main( void )
{
short a = 30000, b = 10000;
long c;

c = a + b;
printf("%ld",c)
return 0;
}
*ただし,short:2バイト,long:4バイト
このプログラムをVisual C++でコンパイルすると
結果は40000とちゃんと表示されるのは何故ですか?
shortは2バイトだからshort型のa + bの値は変な値になるはずで,本来次のようにキャストが必要だと思うのですが。
#include <stdio.h>
int main( void )
{
short a = 30000, b = 10000;
long c;

c =(long) a + b;
printf("%ld",c)
return 0;
}

投稿日時 - 2003-12-02 01:05:07

QNo.720048

困ってます

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

> このプログラムをVisual C++でコンパイルすると
> 結果は40000とちゃんと表示されるのは何故ですか?

C には算術変換というのがあります。

short 型同士の場合,
演算に先立って両オペランドが int 型に変換されます。

int 型が 4 バイトであれば,正しい結果が得られます。

short 型同士以外の場合の算術変換の規則については参考 URL を参照してください。
結構複雑です。

参考URL:http://www.microsoft.com/japan/developer/library/vclang/_pluslang_arithmetic_conversions.htm

投稿日時 - 2003-12-02 01:19:28

補足

yoppiiさんの言われたことを納得するため次のプログラムを比較しました。
#include <stdio.h>
int main( void )
{
int a = 2000000000, b = 1000000000;
float c;

c = a + b;
printf("%f",c);
return 0;
}
では結果が
-1294967296.000000
となり変な結果になります。一方,
#include <stdio.h>
int main( void )
{
int a = 2000000000, b = 1000000000;
float c;

c = (float) a + b;
printf("%f",c);
return 0;
}
では結果が
3000000000.000000
となり正しい結果が得られました。
これはint型同士の場合はfloat型への算術変換が行われていないからということですね!!

投稿日時 - 2003-12-02 01:38:22

お礼

回答ありがとうございます。
>int 型が 4 バイトであれば,正しい結果が得られます。
sizeof演算子を使って調べるとint型は4バイトとなっています。
なるほどそういうことなのですね。

投稿日時 - 2003-12-02 01:32:10

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

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

回答(3)

ANo.3

>c = a + b;
>printf("%f",c);
>return 0;
>}
>では結果が
>-1294967296.000000
>となり変な結果になります。一方,


何故-1294967296.000000 になるか。
理由があります。
intが表せる範囲は-2147483648 ~ 2147483647です。(unsigned intだと0~4294967295です。)
2000000000 + 1000000000は2147483647をオーバーします。
2147483647を超えると値がマイナスになります(2147483647 + 1 → -2147483648)
つまり
3000000000 - 4294967296 → -1294967296となりこの値(int)が暗黙にfloatにキャストされているのです。

投稿日時 - 2003-12-02 10:33:44

補足

この式↓
3000000000 - 4294967296 → -1294967296
の解説をお願いします.

投稿日時 - 2003-12-08 02:32:18

お礼

理由を解説していただきありがとうございました.
ちょっとすぐに理解できなかったので,
sha-girlさんの言われること(例えば,2147483647 + 1 → -2147483648)を理解するため,補数表示について勉強しました.この計算は分かったのですが,でも,
3000000000 - 4294967296 → -1294967296
がちょっとよく分かりませんでした.
補数表示では
n桁のビット表現[a_(n-1),a_(n-2),…,a_1,a_0]_2
を-a_(n-1)2^(n-1)+Σ[k=0 to n-2]a_k2^kに対応させているというのは分かりましたが.

投稿日時 - 2003-12-08 02:32:12

ANo.1

ひとつの式に複数の型の変数がある場合自動で変換されます。
優先度は
char short long float double
 右のほうが優先度が高い
です。

上の例ではコンパイラがlong型に自動で変換します。

投稿日時 - 2003-12-02 01:10:48

お礼

回答ありがとうございます。でも,この場合一つの式の中は同じ型shortですよね。だから,それが理由というのはなかなか素直に納得できないんですが。
ちなみに,
#include <stdio.h>
int main( void )
{
short a = 3, b = 2;
float c;

c = a / b;
printf("%f",c);
return 0;
}
では結果が「1.000000」
#include <stdio.h>
int main( void )
{
short a = 3, b = 2;
float c;

c = (float) a / b;
printf("%f",c);
return 0;
}
では結果は「1.500000」となるのは納得できます。

投稿日時 - 2003-12-02 01:28:32