高精度算法(C/C++)

本文介绍了如何使用C/C++实现高精度算法,包括高精度加法、减法、乘法和除法。通过将大数拆分成固定长度的块进行运算,详细展示了每个操作的原理和C语言实现代码片段。
摘要由CSDN通过智能技术生成

高精度算法 (C/C++)

做ACM题的时候,经常遇到大数的加减乘除,乘幂,阶乘的计算,这时给定的数据类型往往不够表示最后结果,这时就需要用到高精度算法。高精度算法的本质是把大数拆成若干固定长度的块,然后对每一块进行相应的运算。这里以考虑4位数字为一块为例,且输入的大数均为正整数(也可以考虑其他位,但要注意在每一块进行相应运算时不能超出数据类型的数值范围;有负整数的话读入时判断一下正负号在决定运算)。

1. 高精度加法

以3479957928375817 + 897259321544245为例:

3479 9579 2837 5817
+897 +2593 +2154 +4245
= = = =
4376 12172 4991 10062
进位0 进位1 进位0 进位1
4377 2172 4992 0062

C语言实现代码如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 200

//整数乘幂运算函数
int Pow(int a, int b)
{
    int i = 0, result = 1;
    for(i = 0; i < b; ++i)
    {
        result *= a;
    }
    return result;
}


//High Precision Of Addition
int main()
{
    char stra[N], strb[N];      //字符串数组,以字符形式储存两个大数;
    int i = 0, step = 4, carry = 0; //step表示块长,carry为进位位;
    int lengtha, lengthb, maxlength, resultsize;    //maxlength表示stra和strb二者长度较大的那个;
    int numa[N], numb[N],numc[N];   //依次储存被加数,加数,和;
    memset(numa, 0, sizeof(numa));
    memset(numb, 0, sizeof(numb));
    memset(numc, 0, sizeof(numc));         //初始化为零;
    scanf("%s%s", stra, strb);
    lengtha = strlen(stra);
    lengthb = strlen(strb);     //计算两个大数的长度
    //字符数字转为四位一块的整数数字
    for(i = lengtha-1; i >= 0; --i)
    {
        numa[(lengtha-1-i)/step] += (stra[i]-'0')*Pow(10,(lengtha-1-i)%step);
    }
    for(i = lengthb-1; i >= 0; --i)
    {
        numb[(lengthb-1-i)/step] += (strb[i]-'0')*Pow(10,(lengthb-1-i)%step);
    }
    maxlength = lengtha > lengthb ? lengtha : lengthb;

    //逐块相加,并进位
    for(i = 0; i <= maxlength/step; ++i)
    {
        numc[i] = (numa[i] + numb[i])%Pow(10, step) + carry;    //计算和
        carry = (numa[i] + numb[i])/Pow(10, step);  //计算进位
    }

    //计算最后和的块的总数
    resultsize = numc[maxlength/step] > 0 ? maxlength/step : maxlength/step - 1;
    printf("%d", numc[resultsize]);
    for(i = resultsize-1; i >= 0; --i)
    {
        printf("%04d", numc[i]);    //右对齐,补零输出;
    }
    printf("\n");
    return 0;
}
2. 高精度减法

与加法类似,不同的是要注意正负号和显示位数的变化。以99999037289799 - 100004642015000为例:
先判断被减数和减数哪个大,显然这里减数大,故输出结果为负数。在用大数减去小数,(若某一块相减为负数,则要向高位块借

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值