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;
どうして後者の場合はうまくできて、前者の場合はキャストしないといけないのでしょうか?
この辺ご存知の方ご教授願います。
No.1ベストアンサー
- 回答日時:
このマイコン用の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;
と同等になります。
No.2
- 回答日時:
「通常の算術型変換」について調べるとよいでしょう。
話を簡単にするために整数型に限って説明すると...
整数型どうしの算術演算やビット演算では、まず初めに両辺を「整数拡張」します。
「整数拡張」では、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でも実害はありませんが...)。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
- ・ゆるやかでぃべーと タイムマシンを破壊すべきか。
- ・歩いた自慢大会
- ・許せない心理テスト
- ・字面がカッコいい英単語
- ・これ何て呼びますか Part2
- ・人生で一番思い出に残ってる靴
- ・ゆるやかでぃべーと すべての高校生はアルバイトをするべきだ。
- ・初めて自分の家と他人の家が違う、と意識した時
- ・単二電池
- ・チョコミントアイス
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Windows Formアプリからコンソ...
-
QT(C++)の学習方法について
-
C言語について。
-
[C言語]fputsとfprintfの違い
-
パソコン
-
プログラミングの課題がわから...
-
C++でデスクトップGUIアプリ開...
-
int16_t の _t は何?
-
UART通信の取説で,left floati...
-
c言語
-
【C言語】全角文字の配列を、全...
-
PC画面を録画するプログラムでd...
-
今ってプログラミング言語は何...
-
C言語 列挙型(enum型)変数について
-
C言語 バッファについて。
-
const char** p;のとき、free(p...
-
C#でログファイルにファイルパ...
-
Notepad++の関数リスト表示の変...
-
VisualStudio2022でC言語プログ...
-
c言語でイベントフラグを使った...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
構造体のメンバをfor文で回したい
-
mailto:の本文に文字数制限はあ...
-
batファイルでtelnetを起動⇒文...
-
mailto:の中に&を入れる
-
動的にプロパティ名を変えたい
-
R8Cマイコンの乗算
-
時間の平均値を計算する方法を...
-
「HSP」で左クリック判定がうま...
-
mailtoで宛先を日本語で指定す...
-
PythonでのSQL文の書き方を教え...
-
UWSCで出目画像カウントしたい
-
メール送信時にX-Mailerと生IP...
-
Excel VBA 行を折り返すとエラー
-
ACCESS97のモジュールにSPL...
-
携帯・PCアクセス振り分け IP...
-
Wi-Fiが繋がらなくなりました N...
-
アクセスで有給休暇管理表を作...
-
Oculus Riftが映らない。セット...
-
RTX810でローカルルータとして...
-
outlookのアドレス帳について
おすすめ情報