![](http://oshiete.xgoo.jp/images/v2/pc/qa/question_title.png?5a7ff87)
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で質問しましょう!
似たような質問が見つかりました
- 数学 5組のデータ (xx,yy) = (1.0 , 1.1), (2.0 , 1.0), (3.0 , 2 2023/01/09 16:52
- Java Java 年数計算 3 2023/01/28 10:52
- その他(住宅・住まい) 冬の札幌の暖房器具 4 2022/10/18 07:22
- Yahoo!メール yahooメール使用できなくなった。 1 2022/07/05 11:45
- C言語・C++・C# C言語 共用体について コマンドライン引数で値を2つ入力したときに、argv[2]の値をUNI u1 4 2022/04/25 20:34
- Access(アクセス) アクセス where句を使用して複数条件抽出をするには 2 2022/08/29 13:24
- Excel(エクセル) VBAで組み合わせ算出やCOUNTIFSの処理を高速化したいです。 4 2022/04/07 02:38
- Access(アクセス) アクセス 有効なフィールド名、または式として認識できませんのエラー 3 2022/08/19 11:53
- その他(Microsoft Office) パワークエリの複数ファイルのデータ統合について 3 2022/07/14 17:06
- その他(法律) 肩書きを偽ってメールを送った場合、不正アクセス禁止法違反になるのか? 1 2023/02/18 08:35
関連するカテゴリからQ&Aを探す
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Python、プログラミングについ...
-
C言語階乗の総和を求める
-
c++でテンプレートのコードでわ...
-
バッチファイルで以下のような...
-
C言語 配列と関数の練習問題
-
c言語
-
C言語初心者 ポインタについて...
-
応用情報技術者試験の令和元年...
-
インクリメント演算子のみを用...
-
プログラミングの課題がわから...
-
プログラミングについて。 1つ...
-
c言語
-
C#でログファイルにファイルパ...
-
右ビットシフト
-
Linux Cプログラミングを学ぶた...
-
VisualStudioで、コードを印刷...
-
gcc13.2のバグ?
-
なんで
-
mallocについて
-
システムエンジニアの適正について
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
構造体のメンバをfor文で回したい
-
mailto:の本文に文字数制限はあ...
-
batファイルでtelnetを起動⇒文...
-
mailto:の中に&を入れる
-
動的にプロパティ名を変えたい
-
Bresenhamのアルゴリズムを用い...
-
UWSCで出目画像カウントしたい
-
時間の平均値を計算する方法を...
-
R8Cマイコンの乗算
-
PythonでのSQL文の書き方を教え...
-
「HSP」で左クリック判定がうま...
-
アクセスで有給休暇管理表を作...
-
オンラインゲーム中に、頻繁に...
-
RTX810でローカルルータとして...
-
PINGに応答するメリット,デメリ...
-
Oculus Riftが映らない。セット...
-
パケットの中身について。 始点...
-
YAMAHAルータRT58iでのIPマスカ...
-
ネットワークカード2枚挿し TC...
-
デフォルトドメインの意味
おすすめ情報