パソコン活用研究C&C++究め道

Unsigned型(符号なし型)と符号付き型のテスト
(準備中)

Unsigned型と浮動小数点型の内部構造では、Unsigned型(符号なし型)と符号付き型のデータの
内部構造の説明をしました。

ここでは実際に簡単なプログラムで、その挙動を確認してみます。

まずはChar型(1byte)から
共用体 u_c型を定義しました。char型(符号付き1byte)、unsigned char型(符号なし1byte)をメンバー
としてもたせています。

unsignc.c

#include <stdio.h>
union u_c {
  char i;
  unsigned char ui; }
x; 
int main(void) { printf("x?:"); scanf("%d",&x); printf("char:%d\n",x.i); printf("unsigned:%d", x.ui); return 0; }


128を入力してみた。2進数では10000000となり、符号付き(Char型)では負の値となる。
c:\bcc55\Bin>unsignc
x?:128
char:-128
unsigned:128

c:\bcc55\Bin>unsignc
x?:129
char:-127
unsigned:129

255は2進数では11111111となり、符号付き(Char型)では-1となる
c:\bcc55\Bin>unsignc
x?:255
char:-1
unsigned:255


-1を入力してみた。メモリー上では11111111となっているので、符号なし(Unsigned型)では255となる。
c:\bcc55\Bin>unsignc
x?:-1
char:-1
unsigned:255
c:\bcc55\Bin>unsignc

1byteを超える数値を入力してみた。
x?:256
char:0
unsigned:0
c:\bcc55\Bin>unsignc
x?:257
char:1
unsigned:1
c:\bcc55\Bin>


次はshort型(2byte)でテスト。

unsign.c
#include <stdio.h>
union u_int {
  short i;
  unsigned short ui; }
x; 
int main(void) { printf("x?:"); scanf("%d",&x); printf("int:%d\n",x.i); printf("unsigned:%d", x.ui); return 0; }

16bit整数(2byte)では符号付きの最大数は32767。
c:\bcc55\Bin>unsign
x?:32767
short:32767
unsigned:32767

符号付きの最大数は32767で
32768は符号付きでは-1になる。
c:\bcc55\Bin>unsign
x?:32768
short:-32768
unsigned:32768

符号なしの最大数は65535
これは符号付きでは-1になる
c:\bcc55\Bin>unsign
x?:65535
int:-1
unsigned:65535

65535よりひとつ大きい65536は0になる。
符号付きでは-1 -> 0
c:\bcc55\Bin>unsign
x?:65536
int:0
unsigned:0

-1は符号なしでは65535
c:\bcc55\Bin>unsign
x?:-1
int:-1
unsigned:65535

ひとつ小さい-2は符号なしでは65534
c:\bcc55\Bin>unsign
x?:-2
int:-2
unsigned:65534


符号付き整数と符号なし整数の大小比較は想定外のエラーを招きやすい
符号付の整数 -1 と符合なし整数を比較する。
-2と比較しようとしても、符号なし整数では65534になってしまうので、意図した結果にはならない。

#include <stdio.h>
short i;
unsigned short ui;
int main(void) {
i=-1; 
 printf("ui?:");
 scanf("%d",&ui);
 if (i < ui) printf("%dより%dのほうが大きい",i,ui);
 if (i == ui) printf("%dと%dは等しい",i,ui);
 if (i > ui) printf("%dより%dの方が小さい", i,ui);
 return 0; }

c:\bcc55\Bin>unsign2
ui?:-2
-1より65534のほうが大きい
c:\bcc55\Bin>unsign2
ui?:-1
-1より65535のほうが大きい
c:\bcc55\Bin>unsign2
ui?:0
-1より0のほうが大きい
c:\bcc55\Bin>unsign2
ui?:1
-1より1のほうが大きい


固定数値で符号付きの-1 と符号なしの1(プログラム上の表記は1U)の大小比較。
コンパイル時に警告が出るが、コンパイルはできる。
実行すると -1>1が真(=True)となっている。

#include <stdio.h>
int main(void) {
 if (-1 < 1U) printf("-1より1の方が大きい");
 if (-1 > 1U) printf("-1より1の方が小さい");
 return 0; }

c:\bcc55\Bin>bcc32 unsign3.c
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
unsign3.c:
警告 W8012 unsign3.c 4: 符号付き値と符号なし値の比較(関数 main )
警告 W8008 unsign3.c 4: 条件が常に真(関数 main )
警告 W8066 unsign3.c 4: 実行されないコード(関数 main )
警告 W8012 unsign3.c 5: 符号付き値と符号なし値の比較(関数 main )
警告 W8008 unsign3.c 5: 条件が常に真(関数 main )
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland

c:\bcc55\Bin>unsign3
-1より1の方が小さい


符号付き整数のほうは固定値(-1)、符号なし整数は変数の場合

#include <stdio.h>
unsigned short ui;

int main(void) {
 printf("ui?:");
 scanf("%d",&ui);
 if (-1< ui) printf("-1より%dのほうが大きい",ui);
 if (-1== ui) printf("-1と%dは等しい",ui);
 if (-1 > ui) printf("-1より%dの方が小さい",ui);
 return 0; }

c:\bcc55\Bin>bcc32 unsign4.c
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
unsign4.c:
警告 W8068 unsign4.c 8: 比較において定数が範囲外(関数 main )
警告 W8068 unsign4.c 9: 比較において定数が範囲外(関数 main )
警告 W8068 unsign4.c 10: 比較において定数が範囲外(関数 main )
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland

c:\bcc55\Bin>unsign4
ui?:-2
-1より65534のほうが大きい
c:\bcc55\Bin>unsign4
ui?:-1
-1より65535のほうが大きい
c:\bcc55\Bin>unsign4
ui?:1
-1より1のほうが大きい
c:\bcc55\Bin>

符号付き整数は変数とし、符号なし整数は固定値(1)とした場合

#include <stdio.h>
short i;

int main(void) {
 printf("i?:");
 scanf("%d",&i);
 if (i< 1U) printf("%dより1のほうが大きい",i);
 if (i== 1u) printf("%dと1は等しい",i);
 if (i > 1u) printf("%dより1の方が小さい",i);
 return 0; }

c:\bcc55\Bin>bcc32 unsign5.c
Borland C++ 5.5.1 for Win32 Copyright (c) 1993, 2000 Borland
unsign5.c:
Turbo Incremental Link 5.00 Copyright (c) 1997, 2000 Borland

c:\bcc55\Bin>unsign5
i?:-1
-1より1のほうが大きい
c:\bcc55\Bin>unsign5
i?:1
1と1は等しい
c:\bcc55\Bin>unsign5
i?:2
2より1の方が小さい
c:\bcc55\Bin>


算術演算や比較において行われる暗黙の型変換のルールについては
キャスト演算とオートキャスト#算術の型変換」をご参照下さい。




TopPage