コード
- 2の補数表現かつ算術右シフトを行う処理系を想定
1 #include <stdio.h>
2
3 void printf_bit_uc(unsigned char);
4 void printf_bit_c(signed char);
5 void printf_bit_us(unsigned short);
6 void printf_bit_s(signed short);
7 void printf_bit_ui(unsigned int);
8 void printf_bit_i(signed int);
9
10 int main()
11 {
12 unsigned char a;
13 signed char b;
14 unsigned short c;
15 signed short d;
16 unsigned int e;
17 signed int f;
18
19 printf("unsigned char\n");
20 scanf("%d", &a);
21 printf_bit_uc(a);
22 putchar('\n');
23
24 printf("signed char\n");
25 scanf("%d", &b);
26 printf_bit_c(b);
27 putchar('\n');
28
29 printf("unsigned short\n");
30 scanf("%d", &c);
31 printf_bit_us(c);
32 putchar('\n');
33
34 printf("signed short\n");
35 scanf("%d", &d);
36 printf_bit_s(d);
37 putchar('\n');
38
39 printf("unsigned int\n");
40 scanf("%d", &e);
41 printf_bit_ui(e);
42 putchar('\n');
43
44 printf("signed int\n");
45 scanf("%d", &f);
46 printf_bit_i(f);
47
48 return 0;
49 }
50
51 void printf_bit_uc(unsigned char x)
52 {
53 int i;
54 int renzoku;
55 int y;
56 char a[9];
57
58 if (x == 0) {
59 putchar('0');
60 return;
61 }
62 else {
63 for (i = 7; i >= 0; i--) {
64 y = x & 1;
65 if (y) {
66 a[i] = '1';
67 }
68 else {
69 a[i] = '0';
70 }
71 x = x >> 1;
72 }
73 }
74
75 a[8] = '\0';
76 renzoku = 1;
77
78 for (i = 0; a[i] != '\0'; i++) {
79 if (a[i] == '1' && renzoku == 1) {
80 putchar(a[i]);
81 renzoku = 0;
82 }
83 else if (renzoku == 0) {
84 putchar(a[i]);
85 }
86 }
87
88 return;
89 }
90
91 void printf_bit_c(signed char x)
92 {
93 int i;
94 int renzoku;
95 int y;
96 char a[9];
97
98 if (x == 0) {
99 putchar('0');
100 return;
101 }
102 else {
103 for (i = 7; i >= 0; i--) {
104 y = x & 1;
105 if (y) {
106 a[i] = '1';
107 }
108 else {
109 a[i] = '0';
110 }
111 x = x >> 1;
112 }
113 }
114
115 a[8] = '\0';
116 renzoku = 1;
117
118 for (i = 0; a[i] != '\0'; i++) {
119 if (a[i] == '1' && renzoku == 1) {
120 putchar(a[i]);
121 renzoku = 0;
122 }
123 else if (renzoku == 0) {
124 putchar(a[i]);
125 }
126 }
127
128 return;
129 }
130
131 void printf_bit_us(unsigned short x)
132 {
133 int i;
134 int renzoku;
135 int y;
136 char a[17];
137
138 if (x == 0) {
139 putchar('0');
140 return;
141 }
142 else {
143 for (i = 15; i >= 0; i--) {
144 y = x & 1;
145 if (y) {
146 a[i] = '1';
147 }
148 else {
149 a[i] = '0';
150 }
151 x = x >> 1;
152 }
153 }
154
155 a[16] = '\0';
156 renzoku = 1;
157
158 for (i = 0; a[i] != '\0'; i++) {
159 if (a[i] == '1' && renzoku == 1) {
160 putchar(a[i]);
161 renzoku = 0;
162 }
163 else if (renzoku == 0) {
164 putchar(a[i]);
165 }
166 }
167
168 return;
169 }
170
171 void printf_bit_s(signed short x)
172 {
173 int i;
174 int renzoku;
175 int y;
176 signed short a[17];
177
178 if (x == 0) {
179 putchar('0');
180 return;
181 }
182 else {
183 for (i = 15; i >= 0; i--) {
184 y = x & 1;
185 if (y) {
186 a[i] = '1';
187 }
188 else {
189 a[i] = '0';
190 }
191 x = x >> 1;
192 }
193 }
194
195 a[16] = '\0';
196 renzoku = 1;
197
198 for (i = 0; a[i] != '\0'; i++) {
199 if (a[i] == '1' && renzoku == 1) {
200 putchar(a[i]);
201 renzoku = 0;
202 }
203 else if (renzoku == 0) {
204 putchar(a[i]);
205 }
206 }
207
208 return;
209 }
210
211 void printf_bit_ui(unsigned int x)
212 {
213 int i;
214 int renzoku;
215 int y;
216 char a[33];
217
218 if (x == 0) {
219 putchar('0');
220 return;
221 }
222 else {
223 for (i = 31; i >= 0; i--) {
224 y = x & 1;
225 if (y) {
226 a[i] = '1';
227 }
228 else {
229 a[i] = '0';
230 }
231 x = x >> 1;
232 }
233 }
234
235 a[32] = '\0';
236 renzoku = 1;
237
238 for (i = 0; a[i] != '\0'; i++) {
239 if (a[i] == '1' && renzoku == 1) {
240 putchar(a[i]);
241 renzoku = 0;
242 }
243 else if (renzoku == 0) {
244 putchar(a[i]);
245 }
246 }
247
248 return;
249 }
250
251 void printf_bit_i(signed int x)
252 {
253 int i;
254 int renzoku;
255 int y;
256 char a[33];
257
258 if (x == 0) {
259 putchar('0');
260 return;
261 }
262 else {
263 for (i = 31; i >= 0; i--) {
264 y = x & 1;
265 if (y) {
266 a[i] = '1';
267 }
268 else {
269 a[i] = '0';
270 }
271 x = x >> 1;
272 }
273 }
274
275 a[32] = '\0';
276 renzoku = 1;
277
278 for (i = 0; a[i] != '\0'; i++) {
279 if (a[i] == '1' && renzoku == 1) {
280 putchar(a[i]);
281 renzoku = 0;
282 }
283 else if (renzoku == 0) {
284 putchar(a[i]);
285 }
286 }
287
288 return;
289 }
コード(行番号なし版)
#include <stdio.h>
void printf_bit_uc(unsigned char);
void printf_bit_c(signed char);
void printf_bit_us(unsigned short);
void printf_bit_s(signed short);
void printf_bit_ui(unsigned int);
void printf_bit_i(signed int);
int main()
{
unsigned char a;
signed char b;
unsigned short c;
signed short d;
unsigned int e;
signed int f;
printf("unsigned char\n");
scanf("%d", &a);
printf_bit_uc(a);
putchar('\n');
printf("signed char\n");
scanf("%d", &b);
printf_bit_c(b);
putchar('\n');
printf("unsigned short\n");
scanf("%d", &c);
printf_bit_us(c);
putchar('\n');
printf("signed short\n");
scanf("%d", &d);
printf_bit_s(d);
putchar('\n');
printf("unsigned int\n");
scanf("%d", &e);
printf_bit_ui(e);
putchar('\n');
printf("signed int\n");
scanf("%d", &f);
printf_bit_i(f);
return 0;
}
void printf_bit_uc(unsigned char x)
{
int i;
int renzoku;
int y;
char a[9];
if (x == 0) {
putchar('0');
return;
}
else {
for (i = 7; i >= 0; i--) {
y = x & 1;
if (y) {
a[i] = '1';
}
else {
a[i] = '0';
}
x = x >> 1;
}
}
a[8] = '\0';
renzoku = 1;
for (i = 0; a[i] != '\0'; i++) {
if (a[i] == '1' && renzoku == 1) {
putchar(a[i]);
renzoku = 0;
}
else if (renzoku == 0) {
putchar(a[i]);
}
}
return;
}
void printf_bit_c(signed char x)
{
int i;
int renzoku;
int y;
char a[9];
if (x == 0) {
putchar('0');
return;
}
else {
for (i = 7; i >= 0; i--) {
y = x & 1;
if (y) {
a[i] = '1';
}
else {
a[i] = '0';
}
x = x >> 1;
}
}
a[8] = '\0';
renzoku = 1;
for (i = 0; a[i] != '\0'; i++) {
if (a[i] == '1' && renzoku == 1) {
putchar(a[i]);
renzoku = 0;
}
else if (renzoku == 0) {
putchar(a[i]);
}
}
return;
}
void printf_bit_us(unsigned short x)
{
int i;
int renzoku;
int y;
char a[17];
if (x == 0) {
putchar('0');
return;
}
else {
for (i = 15; i >= 0; i--) {
y = x & 1;
if (y) {
a[i] = '1';
}
else {
a[i] = '0';
}
x = x >> 1;
}
}
a[16] = '\0';
renzoku = 1;
for (i = 0; a[i] != '\0'; i++) {
if (a[i] == '1' && renzoku == 1) {
putchar(a[i]);
renzoku = 0;
}
else if (renzoku == 0) {
putchar(a[i]);
}
}
return;
}
void printf_bit_s(signed short x)
{
int i;
int renzoku;
int y;
signed short a[17];
if (x == 0) {
putchar('0');
return;
}
else {
for (i = 15; i >= 0; i--) {
y = x & 1;
if (y) {
a[i] = '1';
}
else {
a[i] = '0';
}
x = x >> 1;
}
}
a[16] = '\0';
renzoku = 1;
for (i = 0; a[i] != '\0'; i++) {
if (a[i] == '1' && renzoku == 1) {
putchar(a[i]);
renzoku = 0;
}
else if (renzoku == 0) {
putchar(a[i]);
}
}
return;
}
void printf_bit_ui(unsigned int x)
{
int i;
int renzoku;
int y;
char a[33];
if (x == 0) {
putchar('0');
return;
}
else {
for (i = 31; i >= 0; i--) {
y = x & 1;
if (y) {
a[i] = '1';
}
else {
a[i] = '0';
}
x = x >> 1;
}
}
a[32] = '\0';
renzoku = 1;
for (i = 0; a[i] != '\0'; i++) {
if (a[i] == '1' && renzoku == 1) {
putchar(a[i]);
renzoku = 0;
}
else if (renzoku == 0) {
putchar(a[i]);
}
}
return;
}
void printf_bit_i(signed int x)
{
int i;
int renzoku;
int y;
char a[33];
if (x == 0) {
putchar('0');
return;
}
else {
for (i = 31; i >= 0; i--) {
y = x & 1;
if (y) {
a[i] = '1';
}
else {
a[i] = '0';
}
x = x >> 1;
}
}
a[32] = '\0';
renzoku = 1;
for (i = 0; a[i] != '\0'; i++) {
if (a[i] == '1' && renzoku == 1) {
putchar(a[i]);
renzoku = 0;
}
else if (renzoku == 0) {
putchar(a[i]);
}
}
return;
}
実行結果
| データ型 | 入力値 | 表示される2進数 | 表示ビット数 |
|---|---|---|---|
unsigned char |
2 |
10 |
2ビット |
signed char |
-1 |
11111111 |
8ビット |
unsigned short |
1024 |
10000000000 |
11ビット |
signed short |
-1024 |
1111110000000000 |
16ビット |
unsigned int |
32768 |
1000000000000000 |
16ビット |
signed int |
-32768 |
11111111111111111000000000000000 |
32ビット |
※ 正の値は先頭の 0 を省略して表示しているため、表示ビット数は型のビット幅ではなく実際に出力された桁数です。負の値は2の補数表現で表示されるため、上位ビットが1で埋まります。
解説
今回作成した6個の関数は型により定義が多少違いますが、基本的な構造は同じであるためprintf_bit_uc関数に焦点を当てます。
51 void printf_bit_uc(unsigned char x)
52 {
53 int i;
54 int renzoku;
55 int y;
56 char a[9];
57
58 if (x == 0) {
59 putchar('0');
60 return;
61 }
62 else {
63 for (i = 7; i >= 0; i--) {
64 y = x & 1;
65 if (y) {
66 a[i] = '1';
67 }
68 else {
69 a[i] = '0';
70 }
71 x = x >> 1;
72 }
73 }
74
75 a[8] = '\0';
76 renzoku = 1;
77
78 for (i = 0; a[i] != '\0'; i++) {
79 if (a[i] == '1' && renzoku == 1) {
80 putchar(a[i]);
81 renzoku = 0;
82 }
83 else if (renzoku == 0) {
84 putchar(a[i]);
85 }
86 }
87
88 return;
89 }
printf_bit_uc 関数ではunsigned char型を1バイトと仮定しているため、入力された10進数値に対応する2進数を文字格納するために、要素数9の char 型配列を定義します(文字0と1の羅列 + 終端ヌル文字分)。また、変数renzoku を定義します。このrenzoku の値が 1 の場合は現在まで 0 が連続している状態であり、0 の場合は、すでにあるビット位置で 1 が現れたことを意味します。
最初に、x に格納されている値が 0 ならば、文字の 0 を表示して処理を終了します。
58 if (x == 0) {
59 putchar('0');
60 return;
61 }
62 else {
x が 0 でない場合はfor 文を用いて x の右端の1ビットをマスクします。これにより、x の最下位ビットが 1 なら y に 1 が格納され、最下位ビットが 0 なら y に 0 が格納されます。これに加え、後続のIf判定により配列の現在の位置iに対応する文字としての数値を格納した後(注: ビットを位の小さい側から切り出す実装のため、iは0からではなく後ろの7から)x を右に1ビットシフトします。これにより、現在確認したビットが切り捨てられ、次に確認するビットが最下位ビットの位置に移動します。
62 else {
63 for (i = 7; i >= 0; i--) {
64 y = x & 1;
65 if (y) {
66 a[i] = '1';
67 }
68 else {
69 a[i] = '0';
70 }
71 x = x >> 1;
72 }
73 }
この処理を繰り返すことで、各ビットを右端から順番に確認し、そのビットに対応する文字 '0' または '1' を配列に格納します。全てのビットを格納した後、配列の終端にヌル文字を付けます。
51 void printf_bit_uc(unsigned char x)
52 {
53 int i;
54 int renzoku;
55 int y;
56 char a[9];
57
58 if (x == 0) {
59 putchar('0');
60 return;
61 }
62 else {
63 for (i = 7; i >= 0; i--) {
64 y = x & 1;
65 if (y) {
66 a[i] = '1';
67 }
68 else {
69 a[i] = '0';
70 }
71 x = x >> 1;
72 }
73 }
74
75 a[8] = '\0';
次に、先ほど説明した renzoku を利用して先頭の不要な 0 は表示せず、配列に格納された2進数を画面に表示します。まず、値を1にして現在まで 0 が連続しているとみなします。
76 renzoku = 1;
以下の条件文により最初の 1 が現れたか判定します。a[i] が 1 かつ renzoku が 1 ならば、現在まで 0 が連続していて、今回初めて 1 が現れたことになります。その場合は 1 を画面に表示し、renzokuを0にすることで、それ以降の0 と 1 の両方を画面に表示します。
76 renzoku = 1;
77
78 for (i = 0; a[i] != '\0'; i++) {
79 if (a[i] == '1' && renzoku == 1) {
80 putchar(a[i]);
81 renzoku = 0;
82 }
83 else if (renzoku == 0) {
84 putchar(a[i]);
85 }
86 }
87
88 return;
89 }
以上となります。お疲れ様でした。