dポイントプレゼントキャンペーン実施中!

R8C34Mを使っています。
例えば下記のコードを実行したら
 unsigned long kai;
 unsigned int xx;
 unsigned int yy;

xx = 0x07d0;  //10進で2000
yy = 0x0064;  //10進で100
kai = xx * yy;

kaiは 0x30d40 となるはずが、0x0d40 でした。
kai = (unsigned long)xx * yy;
と書き直したら、うまくいきました。
答えが2バイトを超えるのが分かっていたのでkaiはlong長にしました。
どうして右辺もキャストでlong長にしないといけないのでしょうか?

また、下記のようにkaiをint長、xx,yyをchar長にした場合は、
kaiは意図する値の0x4e20 になりました。
 unsigned int kai;
 unsigned char xx;
 unsigned char yy;

xx = 0x00c8;  //10進で200
yy = 0x0064;  //10進で100
kai = xx * yy;

どうして後者の場合はうまくできて、前者の場合はキャストしないといけないのでしょうか?
この辺ご存知の方ご教授願います。

A 回答 (2件)

このマイコン用のCコンパイラはよくわからないですが、


通常のCコンパイラのケースでは、int以下のサイズの整数は、intに暗黙にキャストされてから演算します。

http://ja.wikipedia.org/wiki/%E6%B1%8E%E6%95%B4% …

unsigned int kai;
unsigned char xx;
unsigned char yy;
kai = xx * yy;

kai = (unsigned int)( (int)xx * (int)yy) ;
のようなものです。int同士の乗算なので、答えは int型。 共に正なので、積も正です。
この計算結果をunsigned intのに変換して変数kaiに代入します。



unsigned long kai;
unsigned int xx;
unsigned int yy;

kai = xx * yy;

こちらの場合は、xx,yy共にunsigned int なので、型変換は発生しません。
よって、計算結果も、unsigned intのままです。
これをunsinged longに変換してkaiに代入しますが、unsigned intで溢れた桁が戻ってくるわけではありません。


kai = (unsigned long)xx * yy;

これだと、 unsigned long と unsigned int の計算になるので、大きい方に合わせるため
kai = (unsigned long)xx * (unsigned long)yy;
と同等になります。
    • good
    • 0
この回答へのお礼

ありがとうございます。

お礼日時:2013/08/08 22:15

「通常の算術型変換」について調べるとよいでしょう。


話を簡単にするために整数型に限って説明すると...

整数型どうしの算術演算やビット演算では、まず初めに両辺を「整数拡張」します。
「整数拡張」では、int型より(実際の表現範囲が)小さい整数型はすべてint型に変換されます。
char, signed char, short型の表現範囲がint型と同じ場合もint型に変換されます。
また、char, unsigned char, unsigned short型の表現範囲がunsigned int型と同じであればunsigned int型に変換されます。

次に両辺(今回の場合はxxとyy)の型を比べて、より大きい型に変換されます。
このとき、たとえば、int型とunsigned long型ではunsigned long型の方が多いので、unsigned long型に変換されます。元々マイナスの値だったint型のオペランドが符号無しになってしまうので要注意です。

今回のケースでは、unsigned int型のxxとyyは、「通常の算術型変換」ではunsigned int型のままです。
unsigned int型どうしの乗算結果もunsigned int型になりますので、演算結果が表現範囲を超えています。

また、unsigned char型のxxとyyは、「通常の算術型変換」でいずれもint型に変換されます。
int型どうしの乗算結果はint型ですので期待どおりの結果になっています。
なお、今回の場合は演算結果が0x4e20なので問題ありませんが、INT_MAXを超えてオーバーフローすると未定義の動作になります(ただし、R8Cの場合は、HEWでもGCCでも実害はありませんが...)。
    • good
    • 0
この回答へのお礼

ありがとうございます。

お礼日時:2013/08/08 22:16

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!