同じ型の符号なしデータを符号ありデータにキャストする場合、システムはデータの中に格納されている値を評価することなく、型の変換のみを行います。
このページでは、同じ型の符号なしデータを符号ありデータにキャストする際の注意点について説明します。
以下のようなサンプルコードを用意し、コンパイル→リンクして実行してみます。
#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の値域が間違っていたので修正。
(ご指摘頂いた方、ありがとうございました。)
・頂いたメッセージは管理者のチェックの後、公開されます。
・メッセージの公開を希望されない場合には、「このメッセージを非公開にする」にチェックを入れてください。
・管理者が不適切と判断したメッセージは公開しませんので、予めご了承ください。
まだ評価がありません |
表示できるメッセージはありません。