2. 固定小数点 2 進数 10 進数変換関数 固定小数点の 2 進数を 10 進数に変換する。
2 進数の 0.101 は 10 進数では 0.625 となる.此れを踏まえて,小数点以下 2 進数の
べき指数を与えると,10 進数の小数を double 型で返す関数 c2tod10 を作成せよ.
関数の入力引数はべき指数を格納するint型とする.べき指数は1~8とする.戻り値はdouble
型で 10 進数小数を返す.入力値に指定された値以外が入力された場合は-1 を戻り値として
返す.上記で例えると,c2tod10(1)を与えると 10 進数の 0.5( =1/21
)を返す関数になる.
この関数を利用して小数点を含む 2 進数を 10 進数に変換するプログラムを作成せよ.
変換プログラムの入力は 1~4 桁(文字)の整数部及び 0 桁(文字)以上の小数とする.整
数部と小数部の間には小数点(=ピリオド ‘.’)を入力する.なお,小数点は必ずしも整数 4
桁目の後にならないので注意すること.整数部のみの場合(小数点を含め、小数点以下の
入力無し)の入力も考慮すること.入力する 2 進数整数の範囲は“0000”~“1111”迄とし,整
数部が 1 桁未満若しくは 5 桁以上,0,1 及び小数点以外の文字が入力された場合や小数点
が 2 カ所以上存在する場合は“Error”と表示して処理を終了する.また変換できる小数は,2
進数小数点以下 8 桁迄とする.8 桁を超える小数は 8 桁迄 10 進数に変換し,それ以降の数
値については処理を打ち切ること.整数部のみの入力の場合,整数部のみを 10 進数に変換
すること.画面に出力する全てのメッセージは半角英数字で出力すること.
少数2進数を10進数に
Re: 少数2進数を10進数に
小数点以下のべき指数は負の値です。ざこ さんが書きました: 関数の入力引数はべき指数を格納するint型とする.べき指数は1~8とする.
110.101 = 1x22 + 1x21 + 0x20 + 1x2-1 + 0x2-2 + 1x2-3
double型の内部表現は 10進ではなく 2進です。ざこ さんが書きました: 戻り値はdouble型で 10 進数小数を返す.
0.5 (= 2-1 = 1/21) ですね。ざこ さんが書きました: 上記で例えると,c2tod10(1)を与えると 10 進数の 0.5( =1/21 )を返す関数になる.
#include <stdio.h>
double c2tod10(int k)
{
static double t[] = {1./2, 1./4, 1./8, 1./16, 1./32, 1./64, 1./128, 1./256};
unsigned int i = k - 1;
return i < 8 ? t[i] : -1;
}
double conv(const char *s)
{
const char *p; double d = 0; int k;
for (p = s; *p == '0' || *p == '1'; p++)
d = d * 2 + (*p - '0');
if (p == s || p - s > 4) return -1;
if (*p == '.')
for (k = 0; *++p == '0' || *p == '1'; )
if (++k <= 8 && *p == '1') d += c2tod10(k);
if (*p != '\0') return -1;
return d;
}
int main(void)
{
char s[100]; double d;
while (scanf("%99s", s) == 1)
if ((d = conv(s)) == -1) puts("Error");
else printf("%.15g\n", d);
return 0;
}
printf の書式の変換指定 "%g" です。
Re: 少数2進数を10進数に
次のように訂正します。かずま さんが書きました: double の内部2進表現を、文字列の外部2進表現に変換しているのは、
printf の書式の変換指定 "%g" です。
double の内部2進表現を、文字列の10進数に変換しているのは、
printf の書式の変換指定 "%g" です。
蛇足ですが、"%a" を使うと、16進表現の浮動小数点数に変換します。