ACM-ZOJ 1086 八进制小数转十进制 低位高精度除法初步认识

    昨天补马克思笔记真心伤不起,从晚上10点多写到1点半,早上又六点爬起来接着写,所以就没写代码。

    正如标题,今天的主题就是八进制小数转十进制,我也不知道八进制小数有什么用,不过题就让你将八进制转十进制那咱们就转一下。

    这个题读完之后大家基本就会有思路,开始学程序的时候就是28,810,1016,162,基本转一会就懵了……不过现在应该没什么问题了,举一个简单例子:

                   (0.75)[8]= [7*8^(-1) + 5*8^(-2)][10]

这样大概的思路就出来了,就像转上述的例子一样对任何小数进行转换即可。

 但是如果想上述的例子总结公式转换势必会涉及到比较复杂的高精度除法(除高位的),同时计算阶乘的时候会涉及到高精度阶乘(如果示例是16位的就是8^16这个超过了intlong long所以用高精度),同时写除高位的高精度除法要用到高精度减法,这样不仅写代码的压力比较大,而且这个题时间限制是2s,基本就是数据比较恐怖的那种题,就算硬写写出来了,也势必会无情地超时,到时候就看着200多行的代码泪奔去吧。所以我们不仅为程序为电脑也是为自己着想,对上述我们看起来比较简洁的式子进行变化,使得电脑这个不是人的东西觉得式子比较简单(尽管我们看起来亚历山大)于是上式还可以这样写:

                (0.75)[8] = [(5/8 + 7)/8][10]

这种写法可以理解递归。但是书写的时候尽量不要写成递归,递归是用堆内存区,这个数据超大的时候比如递归几百万次堆基本就会爆掉溢出的……不仅计算机伤不起,你也会伤不起,绝对损人不利己……这样按照公式书写即可。

#include <iostream>
#include <cstdio>
#include <cstring>

int main()
{
    char eg[10000];   //输入一个八进制小数
    while ( scanf("%s", eg) != EOF ){
		//输出的十进制小数(没有0.),定义同时进行初始化eg_10[0] = ‘0’
        char eg_10[10000] = {'0'};
		//记录十进制小数的位数
        int index = 0;

        int i(strlen(eg) - 1);//对i定义并初始化,我写的是c++的,c就是i = ……
        for ( ; i != 1; --i ){
            int num = eg[i] - '0';//八进制小数的当前位,同时也是下面计算的余数

			/*****************************************************
             *除8的高精度计算
             */
            int j(0);
			//num也就是余数要除尽。
            for ( ; (j < index )|| num; ++j ){
                int temp = num*10 + (j < index ? eg_10[j] - '0' :0 );
                eg_10[j] = temp/8 + '0';    //商
                num = temp%8;      //余数
            }
			/******************************************************/

            index = j;   //十进制小数的位数
        }

        eg_10[index] = '\0';
        printf("%s [8] = 0.%s [10]\n",eg, eg_10);
    }

    return 0;
}

对低位高精度计算理解其实就是对人进行除法过程的模拟。下图应该很明白的表明了,左面是人进行计算,右面是程序进行的计算。最后希望这篇日志不仅能使大家理解这道题的解法,也对高精度除法有个初步的认识。

《ACM-ZOJ 1086 八进制小数转十进制 低位高精度除法初步认识》

    原文作者:进制转换
    原文地址: https://blog.csdn.net/lancegentry/article/details/7640478
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞