同じ型の符号なしデータを符号ありデータにキャストする場合、システムはデータの中に格納されている値を評価することなく、型の変換のみを行います。
このページでは、同じ型の符号なしデータを符号ありデータにキャストする際の注意点について説明します。
以下のようなサンプルコードを用意し、コンパイル→リンクして実行してみます。
#include <stdio.h>
void main()
{
unsigned int tUnsigned1=4294967295;
signed int tSigned2=-5;
signed int tSigned1;
unsigned int tUnsigned2;
printf("【キャスト前】tUnsigned1=%u\n",tUnsigned1);
printf("\t16進表記 : 0x%02x\n",tUnsigned1);
printf("\t10進符号なし表記 : %4u\n",tUnsigned1);
tSigned1=(signed int)tUnsigned1;
printf("【キャスト後】tSigned1=%d\n",tSigned1);
printf("\t16進表記 : 0x%02x\n",tSigned1);
printf("\t10進符号なし表記 : %4u\n",tSigned1);
printf("【キャスト前】tSigned2=%d\n",tSigned2);
printf("\t16進表記 : 0x%02x\n",tSigned2);
printf("\t10進符号なし表記 : %4u\n",tSigned2);
tUnsigned2=(unsigned int)tSigned2;
printf("【キャスト後】tUnsigned2=%d\n",tUnsigned2);
printf("\t16進表記 : 0x%02x\n",tUnsigned2);
printf("\t10進符号なし表記 : %4u\n",tUnsigned2);
}
上記のコードの実行結果は以下の通りです。
【キャスト前】tUnsigned1=4294967295
16進表記 : 0xffffffff
10進符号なし表記 : 4294967295
【キャスト後】tSigned1=-1
16進表記 : 0xffffffff
10進符号なし表記 : 4294967295
【キャスト前】tSigned2=-5
16進表記 : 0xfffffffb
10進符号なし表記 : 4294967291
【キャスト後】tUnsigned2=4294967291
16進表記 : 0xfffffffb
10進符号なし表記 : 4294967291
同じ型の符号ありデータ⇔符号なしデータのキャストにおいては、その型の中身のデータ値は評価されません。
符号については、「2の補数(2's complement)」で表現されるため、nをビット数とすると、
signedの値域は
- 2(n-1) ≦ x ≦ 2(n-1) - 1
unsignedの値域は
0 ≦ x ≦ 2n- 1
となります。
このため、符号なし⇔符号ありの値のキャストでは、
0 ≦ x ≦ 2(n-1) - 1
以外の値域については、キャストされたデータが意図しない値になることがありますのでご注意ください。
同じ型の符号ありデータ⇔符号なしデータのキャストにおいては、その型の中身のデータ値は評価されず、そのままのデータ値が引き継がれます。
このため、符号なし/符号ありの型が混在した形で計算を行ったり、評価したりする場合、プログラムが意図した動作をしないことがあるので、ご注意ください。
・signed intの値域が間違っていたので修正。
(ご指摘頂いた方、ありがとうございました。)
・頂いたメッセージは管理者のチェックの後、公開されます。
・メッセージの公開を希望されない場合には、「このメッセージを非公開にする」にチェックを入れてください。
・管理者が不適切と判断したメッセージは公開しませんので、予めご了承ください。
| まだ評価がありません |
表示できるメッセージはありません。