- ベストアンサー
型変換キャストについて
#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; }
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
- ベストアンサー
> このプログラムをVisual C++でコンパイルすると > 結果は40000とちゃんと表示されるのは何故ですか? C には算術変換というのがあります。 short 型同士の場合, 演算に先立って両オペランドが int 型に変換されます。 int 型が 4 バイトであれば,正しい結果が得られます。 short 型同士以外の場合の算術変換の規則については参考 URL を参照してください。 結構複雑です。
その他の回答 (2)
- sha-girl
- ベストアンサー率52% (430/816)
>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にキャストされているのです。
お礼
理由を解説していただきありがとうございました. ちょっとすぐに理解できなかったので, 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に対応させているというのは分かりましたが.
補足
この式↓ 3000000000 - 4294967296 → -1294967296 の解説をお願いします.
- ryuta_mo
- ベストアンサー率30% (109/354)
ひとつの式に複数の型の変数がある場合自動で変換されます。 優先度は char short long float double 右のほうが優先度が高い です。 上の例ではコンパイラがlong型に自動で変換します。
お礼
回答ありがとうございます。でも,この場合一つの式の中は同じ型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」となるのは納得できます。
お礼
回答ありがとうございます。 >int 型が 4 バイトであれば,正しい結果が得られます。 sizeof演算子を使って調べるとint型は4バイトとなっています。 なるほどそういうことなのですね。
補足
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型への算術変換が行われていないからということですね!!