算法笔记学习记录——高精度运算

算法笔记学习记录——高精度运算

小学生算术

很多学生在学习加法时,发现“进位”特别容易出错。你的任务时计算两个整数在相加时需要多少次进位。你编程的程序应当可以连续处理多组数据,知道读到两个0(这是输入结束标记)。假设输入的整数都不超过9个数字。
样例输入:
123 456
555 555
123 594
00
样例输出:
0
3
1
分析:
注意int的上限约时2000000000,可以保留所有的9位整数,因此可以用整数来保存输入,每次把a和b分别模10就能获取它的个位数。
代码:

#include <iostream>
#include <stdio.h>
#include <string>
using namespace std;
int main()
{
    int a,b;
    while(scanf("%d%d",&a,&b)==2){//两个都输入了,发回结果就是2
        if(!a&&!b) return 0;
        int c=0,ans=0;//c记录进位,ans记录进位个数
        for(int i=9;i>=0;i--){
            c=(a%10+b%10+c)>9?1:0;//判断是否进位
            ans+=c;
            a/=10;b/=10;//进行下一位的计算
        }
        printf("%d\n",ans);
    }
    return 0;
}

阶乘的精确值

输入不超过1000的正整数n,输出n!=123*…*n的精确结果
样例输入:
30
样例输出:
3652528598121910568636308480000000
分析:
为了保存结果,需要分析1000!有多大。用计算器发现1000!差不多10的2567次方,因此可以考虑用300个元素数组f保存。我们同时要注意,为了方便表示,我们要用数组下标为0的表示各位数(即倒过来)
这样唯一的难度就在于高精度的乘法了,我们使用模拟手算的方式,把结果的每一位都放在了数组的每一位上就解决了。
所以我们分析手算的过程,手算乘法其实就是小学的问题了。即:
先算这一位相乘后再加上上一位的进位的结果数值s,然后对这个结果对10取余得到这一位的本位值f【i】。对这个结果对10除,得到这一位向高位的进位数c。

代码:

#include <iostream>
#include <stdio.h>
#include <string.h>
using namespace std;
const int maxn = 3000;
int f[maxn];
int main()
{
    int i,j,n;
    cin>>n;
    memset(f,0,sizeof(f));//一个初始化函数,string.h才有,把f里所有值赋0
    f[0]=1;
    for(int i=2;i<=n;i++){//进行阶乘
        int c=0;//c表示进位,第一次进位为0
        for(j=0;j<=maxn;j++){
            int s=f[j]*i+c;//计算没一位的相乘后的值
            f[j]=s%10;//对得到的值取余,获得这一位的数值
            c=s/10;//获得这一位的进位
        }
    }
    for(j=maxn-1;j>=0;j--) if(f[j]) break;//忽略前导0
    for(i=j;i>=0;i--) cout<<f[i];//输出
    cout<<endl;
    return 0;
}

当然,对于一些高精度的库函数,可以考虑使用bign类的高精度运算类模板来使用

发布了25 篇原创文章 · 获赞 20 · 访问量 3262

猜你喜欢

转载自blog.csdn.net/qq_44886056/article/details/104008362