编程任务:将 0~1 之间的八进制小数,转换为等值的十进制数。程序的输入是八进制数,每行一个,分别转换成十进制数。输入数据的格式为 0.d1d2d3…dk,其中 di 为八进制数值(0…7),k 值没有限制。
程序输出格式:0.d1d2d3 … dk [8] = 0.D1D2D3 … Dm [10] 左边是输入的八进制数,而右边是等值的十进制数。小数后面没有拖零,也就是 Dm不为 0
【算法分析】
本题需要将八进制表示的小数用十进制数精确地表示,由于位数很多,需要采用高精度的方法计算。用数学公式表达这种转换关系:
${(0.75)_8}$ = ${(7 \* 8 ^ {-1} + 5 \*8 ^{-2})}$$_1$$_0$ 被除数和除数都要使用高精度运算,编程是比较麻烦的。改变一下计算公式:
${(0.75)_8}$ = ${(7 \* 8 ^ {-1} + 5 \*8 ^{-2})}$$_1$$_0$ ==((5/8+7)/8)$_1$$_0$ =(0.93125)$_1$$_0$也就是采用累除的方法,计算起来就很方便。从八进制小数的最低位开始,除以 8 后,与其前一位相加,一直到小数点后的第一位小数。如上例数据,只有两个小数位,分两步运算:
① 5/8=0.615
②(0.625+7)/8=0.93125
这样,我们只要实现除以 8 的高精度运算。
#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>
#include <string.h>
#define ManN 100
int main()
{
char src[ManN];
int i, j;
while (scanf("%s", src) != EOF)
{
char dest[ManN] = { '0' };
int index = 0;
for (int i = strlen(src) - 1; i > 1 ; i--)
{
int num = src[i] - '0';
int temp;
for (j = 0; j < index || num; j++)
{
temp = num * 10 + (j < index ? dest[j] - '0' : 0);
dest[j] = temp / 8 + '0';
num = temp % 8;
}
index = j;
}
dest[j] = '\0';
printf("%s [8] = 0.%s [10]\n", src, dest);
}
return 0;
}
|