第二期四则运算的高精度(非stl)

一.思想

高精度算法在处理超级大数字的时候是十分必要的,用数组来模拟四则运算的过程,也是很简单的算法,在小学时期就学过四则运算的法则,在纸上模拟一遍就会了。


二.高精度加法

题目:
题目

#include <bits/stdc++.h>
using namespace std;
int a[505000], c[505000], b[505000];//a为数字1,b为数字2,c来存答案
string e, f;//因为数太大用string先存着
int main()
{
    cin >> e >> f;
    int le = e.size();
    int lf = f.size();
    for (int i = 1; i <= le; i++)//根据运算法则逆位存储
    {
        a[i] = e[le - i] - '0';
        cout << a[i];
    }
    for (int i = 1; i <= lf; i++)//同理 逆位存储
        b[i] = f[lf - i] - '0';
    int lc = max(e.size(), f.size()) + 1;//c数组大小大1,因为可能有进位
    for (int i = 1; i <= lc; i++)
    {
        c[i] += b[i] + a[i];//先讲a数组和b数组的位数相加
        c[i + 1] = c[i] / 10;//进位
        c[i] = c[i] % 10;//当前位置的值,%即可得到
    }
    while (c[lc] == 0 && lc > 0)//去前导0
        lc--;
    for (int i = lc; i > 0; i--)//反向输出
        cout << c[i];
}

二.高精度减法

高精度减法

#include <bits/stdc++.h>
using namespace std;
string e, f, g;
int le, lf, flag = 0;
int a[100005], b[100005], c[100005];//c存答案的数组
bool cmp(string e, string f)
{
    if (le != lf)//先看长度
        return le > lf;
    for (int i = 0; i < le; i++)//长度一样 看位数大小
    {
        if (e[i] != f[i])
            return e[i] > f[i];
    }
    return false;//相同的情况
}

int main()
{
    cin >> e >> f;
    le = e.size();
    lf = f.size();
    if (!cmp(e, f))//一定要把大的数放在前面!
    {
        swap(e, f);
        swap(le, lf);
        flag = 1;//记得变号哦
    }
    for (int i = 1; i <= le; i++)//反向存储
    {
        a[i] = e[le - i] - '0';
    }
    for (int i = 1; i <= lf; i++)//反向存储
    {
        b[i] = f[lf - i] - '0';
    }
    int lc = max(le, lf);
    for (int i = 1; i <= lc; i++)
    {
        if (a[i] < b[i])//按照减法运算可以轻易得出
        {
            a[i + 1]--;//前位取1
            a[i] += 10;//这位进10
        }
        c[i] = a[i] - b[i];//一减就是该位数
    }
    while (c[lc] == 0 && lc > 0)//去前导0
        lc--;
    if (flag == 1)//换数了的话记得变号哦
        cout << '-';
    for (int i = lc; i > 0; i--)//反向输出
        cout << c[i];
    return 0;
}

有几点需要注意:
1.要把大的放在前面。
2.换数要变号。


三.高精度乘法

大数乘小数

这个用一下stl和数组模拟差不多,但是数组不好确定最终答案c的长度,其实还是stl好用点,但是会一个也就会另一个。

在开乘

#include <bits/stdc++.h>
using namespace std;
string s;
vector<int> a, c;//都是老样子了
int b;
int main()
{
    cin >> s;
    cin >> b;
    for (int i = s.size() - 1; i >= 0; i--)// 依旧反向存储./
    {
        a.push_back(s[i] - '0');
    }
    int t = 0;
    for (int i = 0; i < a.size() || t; i++)//注意这个t哦 万一有剩余的余数可以给他加上
    {//根据四则运算很好得出下面
        if (i < a.size())
            t += a[i] * b;
        c.push_back(t % 10);//老样子%为该数
        t /= 10;//进位
    }
    while (c.size() > 1 && c.back() == 0)
        c.pop_back();//去前导0
    for (int i = c.size() - 1; i >= 0; i--)//依旧反向输出./
        cout << c[i];
    return 0;
}

大数乘大数

两个超级大数相乘 上代码:

#include <bits/stdc++.h>
using namespace std;
string s1, s2;
int a[100005], b[100005], c[100005];

int main()
{
    cin >> s1 >> s2;
    int la = s1.size();
    int lb = s2.size();
    if(la==1&&s1[0]==0)
    {
        cout << 0;
        return 0;
    }
    if(lb==1&&s2[0]==0)
    {
        cout << 0;
        return 0;
    }
    for (int i = 1; i <= la; i++)
    {
        a[i] = s1[la - i] - '0';
    }
    for (int i = 1; i <= lb; i++)
    {
        b[i] = s2[lb - i] - '0';
    }
    int lc = la + lb;
    for (int i = 1; i <= la; i++)//看下面的原理讲解,然后就和上面的大乘小一样了
    {
        for (int j = 1; j <= lb; j++)
        {
            c[i + j - 1] += a[i] * b[j];
            c[i + j] += c[i + j - 1] / 10;
            c[i + j - 1] %= 10;
        }
    }
    while (c[lc] == 0 && lc > 0)
        lc--;
    for (int i = lc; i > 0; i--)
    {
        cout << c[i];
    }
    return 0;
}

原理
我们可以得出a的下标加b的下标再减一就是c的下标!!!

四.高精度除法

除除除

#include <bits/stdc++.h>
using namespace std;
int a[1000005], b;
string s;
int c[100005];
int main()
{
    int x = 0;
    cin >> s >> b;
    int la = s.size();
    if (s[0] == '0')
    {
        cout << 0;
        return 0;
    }
    for (int i = 0; i < la; i++)//根据除法法则 不用逆序存储
        a[i] = s[i] - '0';
    for (int i = 0; i < la; i++)
    {//根据除法运算也很好得出
        c[i] = (x * 10 + a[i]) / b;//该数字等于余数乘10+下面的数再除以b
        x = (x * 10 + a[i]) % b;//求余数
    }
    int lc = 0;
    while (c[lc] == 0 && lc + 1 < la)//去前导0
        lc++;
    for (int i = lc; i < la; i++)//不用逆序存储也不用逆序输出
    {
        cout << c[i];
    }
    cout << endl;
    cout << x;
    return 0;
}

总结

高精度还是比较简单的,但是需要巩固和训练,多敲几遍即可烂熟于心!!!加油努力!!!
kon!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值