はじめに

同じ型の符号なしデータを符号ありデータにキャストする場合、システムはデータの中に格納されている値を評価することなく、型の変換のみを行います。

このページでは、同じ型の符号なしデータを符号ありデータにキャストする際の注意点について説明します。

サンプルコード

以下のようなサンプルコードを用意し、コンパイル→リンクして実行してみます。

サンプルコード
#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

以外の値域については、キャストされたデータが意図しない値になることがありますのでご注意ください。

結論

同じ型の符号ありデータ⇔符号なしデータのキャストにおいては、その型の中身のデータ値は評価されず、そのままのデータ値が引き継がれます。

このため、符号なし/符号ありの型が混在した形で計算を行ったり、評価したりする場合、プログラムが意図した動作をしないことがあるので、ご注意ください。

変更履歴

2023/07/28

・signed intの値域が間違っていたので修正。
(ご指摘頂いた方、ありがとうございました。)


あなたの探し物は見つかりましたか?
まさにこれだ
参考になった
ちょっと違う
これじゃない

何かメッセージがあればお願いします

このメッセージを非公開にする

ご注意

・頂いたメッセージは管理者のチェックの後、公開されます。
・メッセージの公開を希望されない場合には、「このメッセージを非公開にする」にチェックを入れてください。
・管理者が不適切と判断したメッセージは公開しませんので、予めご了承ください。


まさにこれだ
31 (49%)
参考になった
18 (29%)
ちょっと違う
6 (10%)
これじゃない
8 (13%)

表示できるメッセージはありません。