有关大数的运算(1)

大数运算有很多种形式,今天我们将不同的情况进行归纳总结:(Ps:已经写好string和int之间转换的函数,以及去掉不必要的0之类的辅助小函数 )

[0]:首先实现大数求余的情况1 : A%B(A很大B可以用整数表示),算法也很好理解,用归纳的思想就可以证明.

int Mod(string a, int b)
{
    //遍历大数a的每一位不断求余更新
    int t = 0;
    for (int i = 0; i != a.length(); ++i)
        t = (t * 10 + a[i] - '0') % b;

    return t;
}

[1]:然后实现两个很大的正数相减,如果需要实现负数的话需要再实现正数的加法,然后进行转换.

//每次取6位进行计算,算法效率相对较高
string Subtract(string a, string b)//暂时只能处理两个正数
{
    //首先消除前置的0;
    a = remove_pre_zero(a);
    b = remove_pre_zero(b);
    if (a.length() < b.length())
        return "-" + Subtract(b, a);
    int n =  b.length();
    int  b_pos = n - 6;//b第一段子串的起始点
    int  a_pos = b_pos + a.length() - n;
    int temp, borrow = 0;//borrow是借位标志
    string ans;
    bool test = false;
    for (; !test; b_pos -= 6)
    {
        auto mod = 6;
        if (b_pos <= 0)
        {
            mod = b_pos + 6;
            b_pos = 0,test = true;
        }
        a_pos = b_pos + a.length() - n;
         temp =string_to_int(a.substr(a_pos,mod)) 
            - string_to_int(b.substr(b_pos , mod)) - borrow;//获取该6位的结果
        borrow = 0;//将借位清零
        if (temp < 0)
        {
            if (a_pos>0) 
                temp += string_to_int("1"+string(mod,'0'));
            borrow = 1;
        }
        auto s = int_to_string(temp);

        if (temp>=0)
            ans = string(mod - s.length(), '0') + s + ans;
        else//temp<=0说明前面已经没有高位了,a_pos<=0.
            ans = s + ans;
    }
    if (a_pos > 0)//处理剩下的a的高位
    {
        if (borrow == 1)//有借位
            ans = Subtract(a.substr(0, a_pos), string(a_pos - 1, '0') + '1') + ans;
        else
            ans = a.substr(0, a_pos) + ans;
    }
    return remove_pre_zero(ans);
}

[2]:实现两个大数求求余 A%B(A,B都很巨大,都只能用string来表示),这个函数就是模拟大数除法来计算的,需要用到减法的函数

string Mod(string a, string b)//实现大数求余的第二种情况,a,b都很大
{
    //默认a,b不存在前置的0
    if (a.length() < b.length())//a一定小于b
        return a;
    int n = b.length();//n是b的长度
    int k;
    string temp = a.substr(0, n);
    string old_ans,mod;
    for (int i = n;i!=a.length()+1; ++i)
    {
        for ( k = 0;temp[0] !='-'; ++k)//不断的试探
        {
            old_ans = temp;
            temp = Subtract(temp,b);
        }
        temp = old_ans+a.substr(i, 1);
        --k;//获得该位的商
        if (i == a.length())
            mod = old_ans;
    }
    return mod;
}

[3]大数乘法和加法:在前面的博文已经实现过,这次直接照搬

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值