首页 > 代码库 > HighAccuracy1131

HighAccuracy1131

 

 

题意解释:

给定一个八进制的小数(01之间)题目要求你把它转换为十进制小数,转换后小数的位数是转换前八进制小数位数的3倍且不输出末尾无意义的零(即后置零).

 0.75 in octal is 0.953125 (7/8 + 5/64) in decimal.

 

①先说最直接的想法,从十分位到最后一位,每次乘上8(-i)次方,累加即可,但这样写起高精度来异常麻烦,有可能涉及到高除高。

 

②稍作思考,我们发现从最后一位开始到小数点之前停下来,上一位算出来的数加上这一位的数除以8即可当做当前位算出来的数。

 

例如:0.233  [(3/8+3)/8+2]/8就是答案。

 

但计算机处理如此精度的小数,高精度写的多累啊(高手勿喷)。

 

③于是想到了化小数为整数,每次除以8之前看看能否被8整除(这个判断应该知道吧,看后三位能不能被8整除),不能的话乘10再看,乘10的同时计数器加1,直到能被8整除,除以8

 

 

举个例子

0.75

 

5不能被8整除,5000可以,pos=3  5000/8=625

从最低位开始除,因为位数越低,需要被除的次数越多,这样通过不同位数除以不同次数的8即可完成进制转换。第三个方法是对第二方法的改进。

 

此时不能在625的基础上加7,应该加7*(10^pos),补全你乘的10,得到7625

 

此时7625不能被8整除,而7625000可以

 

pos=6  7625000/8=953125

 

最后输出的时候小数点往前移动pos位即可。

 

整个过程数组模拟计算,否则后果你知道。。

 

 

#include <stdio.h>

 

#include <string.h>

 

int divide(int *a, int len)//大整数除法的思想 //divide(a, len_a)

{

    int residue = 0, next = 0, temp = 0, i;

    for(i = 0; i < len; i++)//首先把len位的数尝试除8

    {

        temp = a[i] + next;

        a[i] = temp / 8;//第一次除的时候,a[i]一定等于0,比较八进制的数都小于8

        residue = temp % 8;

        next = residue * 10;//看成除8操作,那么高位的余数留到低位应该乘10

    }

//此时i=len

    while(next)//除不尽,那么通过将余数乘10的方式继续除8i接着上次继续增加

    {

        a[i++] = next / 8;

        next = next % 8;

        next = next * 10;

    }

   return i;//得到的小数共有多少位

}

 

int main()

{

    char s[1000];

    int a[3000];

    while(scanf("%s", s)!=EOF)

    {

        int n;

        n = strlen(s);

        int i;

        for(i = 0; i < n; i++)     //寻找第一个不是‘0‘或是‘.‘的数

            if(s[i] != ‘0‘ && s[i] != ‘.‘)

                break;

 

if(i >= n)//如果是0

printf("%s [8] = %s [10]\n", s, s);          

else

{

int len_a = 1;//初始时只需要把最低位拿去除即可,只有一位

for(i = n - 1; i > 1; i--)

{

a[0] = s[i] - ‘0‘;    

/*将字符串倒着存入a[0]。新来的s[i]加入上次得到a

数组序列(旧数组中a[0]=0)。len_a返回除完之后的小

数长度(不包括小数点)这样越低位的数,被8除的次数

就越多。十分位被8除一次。百分位被8除两次

*/len_a = divide(a, len_a);

}

 

printf("%s [8] = 0.", s);

for(i = 1; i < len_a; i++)

printf("%d", a[i]);

 

printf(" [10]\n");

}

}

return 0;

 

}

HighAccuracy1131