先回は、Cのプログラムで基数変換してみた。↓
今回は、このプログラムを基数変換の過程を表示するプログラムに変更してみよう。
整数を2進数~36進数に基数変換(変換過程を表示)
// 整数を2進数~36進数に基数変換(変換過程を表示)
#include <stdio.h>
/*--- type型のxとyの値を交換 ---*/
#define swap(type, x, y) do { type t = x; x = y; y = t; } while (0)
/*--- 整数値xをn進数に変換して配列dに下位桁から格納 ---*/
int card_conv(unsigned x, int n, char d[])
{
char dchar[] = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
int digits = 0; // 変換後の桁数
if (x == 0) // 0であれば
d[digits++] = dchar[0]; // 変換後も0
else {
while (x) {
printf("%2d |%7d … %c\n", n, x, dchar[x % n]); //変換過程を表示
printf(" +----------\n");
d[digits++] = dchar[x % n]; // nで割った剰余を格納
x /= n;
}
printf(" %5d\n", x);
}
for (int i = 0; i < digits / 2; i++) // 配列dの並びを反転
swap(char, d[i], d[digits - i - 1]);
return digits;
}
int main(void)
{
puts("10進数を基数変換します。");
int retry; // もう一度?
do {
unsigned no; // 変換する整数
int cd; // 基数
char cno[512]; // 変換後の数値の各桁の数字を格納する文字の配列
printf("変換する非負の整数:");
scanf("%u", &no);
do {
printf("何進数に変換しますか(2-36):");
scanf("%d", &cd);
} while (cd < 2 || cd > 36);
int dno = card_conv(no, cd, cno); // noをdno桁のcd進数に変換
printf("%d進数では", cd);
for (int i = 0; i < dno; i++) // 各桁の文字を順に表示
printf("%c", cno[i]);
printf("です。\n");
printf("もう一度しますか(1…はい/0…いいえ):");
scanf("%d", &retry);
} while (retry == 1);
return 0;
}
実行結果
10進数を基数変換します。
変換する非負の整数:57
何進数に変換しますか(2-36):2
2 | 57 … 1
+----------
2 | 28 … 0
+----------
2 | 14 … 0
+----------
2 | 7 … 1
+----------
2 | 3 … 1
+----------
2 | 1 … 1
+----------
0
2進数では111001です。
もう一度しますか(1…はい/0…いいえ):1
変換する非負の整数:57
何進数に変換しますか(2-36):8
8 | 57 … 1
+----------
8 | 7 … 7
+----------
0
8進数では71です。
もう一度しますか(1…はい/0…いいえ):0
このように、先のプログラムの数行加えるだけで、基数変換の過程を詳細に表示するプログラムへ変更できた。
(参考文献)新・明解C言語で学ぶアルゴリズムとデータ構造第2版 柴田望洋著(SBクリエイティブ)
コメント