【Nan‘s POJ】1001 Exponentiation 高精度算法

【Nan’s POJ】1001 Exponentiation 高精度算法

高精度算法相关

找到一篇入门的博文,感觉写的很详细了,在此转载一下:
https://blog.csdn.net/zsjzliziyang/article/details/82050337

本题思路

主要就是高精度计算的基本思路,实现高精度乘法,用 long long什么的是无法实现的。
Mark几个重点:
①对于很大的数,可先用一个字符串输入。再利用字符串函数等操作将每一位数取出,存入一个整型或short数组里,数组的每一位表示这个数的一个数位
②存入数字一般倒序,123456789用数组储存下来,a{9,8,7,6,5,4,3,2,1}.
原因:最高位可进位,方便存。
③一位小数X一位小数=两位小数,两位X两位 = 四位,三位X三位 = 六位
可知小数位数相同的相乘,结果的小数位数等于原来小数位数的2倍,不同则相加。

本题AC代码

下面的代码参考了Shawon的博文,本人在读懂基础上,增加了注释和优化。

//G++下AC
#include<iostream>
using namespace std;
int main() {
    string r;
    int n, point;
    const int R_LEN = 160;
    short result[R_LEN], jieguo[R_LEN], chengshu[6];
    while (cin >> r >> n) {
        for (int i = 0; i < R_LEN; ++i) jieguo[i] = result[i] = 0;//初始化为0
        for (int i = 0; i < 6; ++i) chengshu[i] = 0;
        point = 0;
        int pos = r.find(".");//C++的find函数找到数值的话,bai就输出。否则,返回string::npos
        if (pos != string::npos) point = (5 - pos) * n; //计算出小数点后有多少位
        for (int i = 5, j = 0; i >= 0; --i) {
            if (r[i] != '.') { //从最后开始查
                jieguo[j] = result[j] = chengshu[j] = r[i] - '0';//提取数位 倒序储存
                ++j;//j正序
            }
        }
        while (n >= 2){//指数大于等于2的时候计算,否则直接去除多余0输出
            --n;
            for (int i = 0; i < R_LEN; ++i) result[i] = 0;
            for (int i = 0; i < 5; ++i){ //乘数数位循环//从个位开始做乘数
                int c;
                for (int j = 0; j < R_LEN; ++j){//被乘数数位循环
                    if (chengshu[i] == 0) break;
                    c = chengshu[i] * jieguo[j];
                    result[i + j] += c;//从i对应位开始存入(类似竖式运算)
                    for (int t = i + j; result[t] > 9; ++t){//处理进位
                        result[t + 1] += result[t] / 10; //进位1
                        result[t] = result[t] % 10; //本位留下余数
                    }
                }
            }
            for (int i = 0; i < R_LEN; ++i) jieguo[i] = result[i];//结果转存,以便下一次循环计算
        }
        int firstindex = -1;
        for (int i = R_LEN - 1; i >= point; --i){//从右往左查找小数点前第一个不为0的数
            if (result[i] > 0) {
                firstindex = i;
                break;
            }
        }
        int lastindex = -1;
        for (int i = 0; i < point; ++i){//从左往右查找小数点前第一个不为0的数
            if (result[i] > 0) {
                lastindex = i;
                break;
            }
        }
        if (firstindex != -1){
            while (firstindex >= point) {
                cout << result[firstindex];//输出小数点前的部分
                --firstindex;
            }
        }
        if (lastindex != -1){//如果有小数部分,先输出小数点,再输出小数部分
            cout << '.';
            --point;
            while (point >= lastindex) {
                cout << result[point];
                --point;
            }
        }
        cout << endl;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值