C++高精度加,减,乘,除运算

  今天,我就来写一个关于高精度算法的总结,首先,我们要知道C++为什么要用到高精度算法,首先我们知道,C++中最大的整数类型就是long long ,最大范围是10的18次方,但是如果超过了10的18次方怎么办,存都存不下,更别谈运算了,这种数被称为高精度数和大整数!

  先给大家说一下高精度的名词:

低精:
直接可以使用 C++ 中有的数据类型进行定义。比如 15,678,808,877 这个数,我们可以用 long long 来定义。

高精加高精:
高精度数加上高精度数。

高精乘高精:
高精度数乘上高精度数。

高精乘低精:
高精度数乘上低精度数。

高精除高精:
高精度数除以高精度数。

高精除低精:
高精度数除以低精度数。

高精度加法

  接下来,我们就可以正式开始高精度运算了,我们先从高精度加法算起,我们在小学二三年级的时候,做一些加法题都需要用到竖式计算,而这种竖式计算是无论多大的数都可以算出来的,所以我们可以借助模拟竖式计算的方法来进行高精度加法运算。

思路:

  1. 定义存储数组。

  2. 读入数据到数组中。注意是倒序存放,也就是个位放在数组下标为 0 的地方。

  3. 从个位开始模拟竖式加法的过程,完成整个加法。

  4. 删除前导 0 。所谓前导零,就是出现类似这样数据 01234,这个 0 实际是不需要的。

  5. 输出加法的结果。倒序输出加法的结果数组 C,因为我们的个位是存储在下标为 0 的地方。

我们先来看一看存储结构:

 
const int N=1e5+10; char s1[N]={};//存储字符串char s2[N]={};//存储字符串int a[N]={};//存储加数Aint b[N]={};//存储加数Bint c[N]={};//存储和C

读入数据:

   我们先输入s1,s2两个字符串,然后再求出两个字符串的长度l1和l2,之后将s1[i]赋值给a[i],将s2[i]赋值给b[i],用int类型数组更容易计算一些!

    scanf("%s %s",s1,s2);    int l1=strlen(s1);    int l2=strlen(s2);    for(int i=0;i<l1; i++)       a[i]=s1[l1-i-1]-'0';    for(int i=0;i<l2;i++)       b[i]=s2[l2-i-1]-'0';

模拟竖式加法:

    首先,我们要将a[i]和b[i]加起来,存到c[i]里面,在将他们的进位存在jw里面,每次运算加上去,哪怕是0,之后再将c[i]对10来取模,是求进位过后这个位是什么数字!

 
//模拟竖式加法    int jw=0;//进位    int l=max(l1,l2)+1;//注意因为最高位可能出现进位    for(int i=0;i<len;i++)     {        c[i]=a[i]+b[i]+jw;//当前加数A位数据+加数B位位数据+上一位的进位        jw=c[i]/10;//本次加法是否存在进位        c[i]%=10;//只能保存0~9的数据    }

有两个细节需要注意:

  1. 进位如何保存;

  2. 最高位进位如何解决。 

删除多余的0:

  由于我们是倒着来的前面有很多多余的0,我们用for循环倒着删除,如果遇到0了,就将c[i]的长度减1,直到碰见第一个不是0的最高位,就break;结束删除!

    //删除前导零    for (int i=l-1;i>=0;i--)     {        //因为我们是从下标0开始,所以最高位是保存在l-1        if(0==c[i]&&l>1)         {            //注意要有 l>1 这个条件。考虑特殊情况,加法结果为 00,我们实际要输出 0。            len--;        }        else         {            //第一个不是零的最高位,结束删除            break;        }    }

输出计算结果: 

  最后就是将计算结果输出就行了,用for循环一个一个来打印!

    //逆序打印输出    for (int i=l-1;i>=0;i--)     {        printf("%d",c[i]);    }    printf("\n");

高精度加法的完整代码:

 
#include <bits/stdc++.h>using namespace std;const int N=200+4; char s1[N]={};//存储字符串char s2[N]={};//存储字符串int a[N]={};//存储加数Aint b[N]={};//存储加数Bint c[N]={};//存储和Bint main() {    scanf("%s %s",s1,s2);//读入字符串A    //将字符串写入到数组A中    int l1=strlen(s1);    for(int i=0;i<l1;i++)     {        //倒序写入        a[i]=s1[len1-i-1]-'0';    }    //将字符串写入到数组A中    int l2=strlen(s2);    for(int i=0;i<len2;i++)     {        //倒序写入        b[i]=s2[len2-i-1]-'0';    }    //模拟竖式加法    int jw=0;//进位    int l=max(l1,l2)+1;//注意因为最高位可能出现进位    for(int i=0;i<l;i++)     {        c[i]=a[i]+b[i]+jw;//当前加数A位数据+加数B位位数据+上一位的进位        jw=c[i]/10;//本次加法是否存在进位        c[i]%=10;//只能保存 0 ~ 9 的数据    }    //删除前导零    for(int i=l-1;i>=0;i--) {        //因为我们是从索引 0 开始,所以最高位是保存在 len-1        if(0==c[i]&&len>1)         {            //注意要有 len>1 这个条件。考虑特殊情况,加法结果为 00,我们实际要输出 0。            l--;        }         else         {            //第一个不是零的最高位,结束删除            break;        }    }     //逆序打印输出    for (int i=l-1; i>=0; i--)     {        printf("%d", c[i]);    }    printf("\n");         return 0;}
 

高精度减法

高精度减法计算原理
在读小学时,我们做减法都采用竖式方法,如图 1 所示。这样,我们可以写出两个整数相减的算法。

wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==编辑

我们就可以用 C++ 语言来模拟这个竖式减法的过程。我们可以考虑利用 C++ 的数组来存储对应数据,假设用数组 A 存储被减数 856 的每一位,具体来说就是 A1 存储个位 6,A2 存储十位 5,A3存储百位 8;类似数组 A 的结构,使用数组 B 存储减数 257;类似数组 A 的结构,使用数组 C 来存储对应的差 599。两数相加的结果就如图 2 所示。这样理论上来说,我们就可以计算无限大的数据。如上图 2 所示,下表表示对应的存储方式。


数组 A数组 B数组 C
[0]679
[1]559
[2]825

总结:利用数组存储,突破存储的限制。每个位置存储 0 ~ 9 之间的数据。

高精度减法实现
思路
1、定义存储数组。

2、被减数和减数确认。由于减法可能出现负数。

3、读入数据到数组中。注意:保证被减数大于减数;倒序存放,也就是个位放在数组下标为 0 的地方。

4、从个位开始模拟竖式减法的过程,完成整个减法。

5、删除前导 0 。所谓前导零,就是出现类似这样数据 01234,这个 0 实际是不需要的。

6、输出减法的结果。倒序输出减法的结果数组 C,因为我们的个位是存储在下标为 0 的地方。

技术细节说明
定义存储数组

根据题目的要求定义数组。这个部分代码如下:

 
const int MAXN = 1e5+4; //根据题目的最大值。+4为了防止A+B出现进位char s1[MAXN] = {};//存储字符串char s2[MAXN] = {};//存储字符串char tmp[MAXN] = {};//交换用字符串int a[MAXN] = {};//存储加数Aint b[MAXN] = {};//存储加数Bint c[MAXN] = {};//存储和B
 

被减数和减数确认

由于减法可能出现负数,如 3-5=-2,我们在计算的时候,实际是使用 5-3=2,最后在结果前面添加负号。如果出现被减数小于减数的情况,要将两者颠倒。

    scanf("%s %s", s1, s2);//读入字符串    int lena = strlen(s1);    int lenb = strlen(s2);    //判断最终的结果符号    if ((lena<lenb) || (lena==lenb && strcmp(s1,s2)<0)) {        //被减数小于减数,结果为负数        printf("-");        //交换数据        strcpy(tmp, s1);        strcpy(s1, s2);        strcpy(s2, tmp);        //更新长度数据        lena = strlen(s1);        lenb = strlen(s2);    }

读入数据到数组

利用读入字符串的方法读入数据,再倒序写入到对应的数组中。这个部分代码如下:

    //将字符串写入到数组A中    for (int i=0; i<lena; i++) {        //倒序写入        a[i] = s1[lena-i-1] - '0';    }     //将字符串写入到数组B中    for (int i=0; i<lenb; i++) {        //倒序写入        b[i] = s2[lenb-i-1] - '0';    }

模拟竖式减法

有两个技术细节:如何判断发生借位。这个部分代码如下:

    //模拟竖式减法    for (int i=0; i<lena; i++) {        if (a[i]<b[i]) {            //有借位            a[i+1]--;            a[i] += 10;        }        c[i] = a[i] - b[i];    }

删除前导零

因为减法运算可能会出现最高位为零,所以我们需要判断是否需要删除前导零。这个部分代码如下:

    //删除前导零    for (int i=lena-1; i>=0; i--) {        //因为我们是从索引 0 开始,所以最高位是保存在 len-1        if (0==c[i] && lena>1) {            //注意要有 lena>1 这个条件。考虑特殊情况,加法结果为 00,我们实际要输出 0。            lena--;        } else {            //第一个不是零的最高位,结束删除            break;        }    }

输出计算结果

采用倒序的方式输出,因为我们数据保存是倒序结构,也就是低位在前。

    //逆序打印输出    for (int i=lena-1; i>=0; i--) {        printf("%d", c[i]);    }    printf("\n");

高精度减法的完整代码: 

 
#include <bits/stdc++.h>using namespace std; const int MAXN = 1e4+4; //根据题目的最大值。+4为了防止A+B出现进位char s1[MAXN] = {};//存储字符串char s2[MAXN] = {};//存储字符串char tmp[MAXN] = {};//交换用字符串int a[MAXN] = {};//存储加数Aint b[MAXN] = {};//存储加数Bint c[MAXN] = {};//存储和B int main() {    scanf("%s %s", s1, s2);//读入字符串        int lena = strlen(s1);    int lenb = strlen(s2);    //判断最终的结果符号    if ((lena<lenb) || (lena==lenb && strcmp(s1,s2)<0)) {        //被减数小于减数,结果为负数        printf("-");        //交换数据        strcpy(tmp, s1);        strcpy(s1, s2);        strcpy(s2, tmp);        //更新长度数据        lena = strlen(s1);        lenb = strlen(s2);    }        //将字符串写入到数组A中    for (int i=0; i<lena; i++) {        //倒序写入        a[i] = s1[lena-i-1] - '0';    }     //将字符串写入到数组B中    for (int i=0; i<lenb; i++) {        //倒序写入        b[i] = s2[lenb-i-1] - '0';    }     //模拟竖式减法    for (int i=0; i<lena; i++) {        if (a[i]<b[i]) {            //有借位            a[i+1]--;            a[i] += 10;        }        c[i] = a[i] - b[i];    }     //删除前导零    for (int i=lena-1; i>=0; i--) {        //因为我们是从索引 0 开始,所以最高位是保存在 len-1        if (0==c[i] && lena>1) {            //注意要有 lena>1 这个条件。考虑特殊情况,加法结果为 00,我们实际要输出 0。            lena--;        } else {            //第一个不是零的最高位,结束删除            break;        }    }     //逆序打印输出    for (int i=lena-1; i>=0; i--) {        printf("%d", c[i]);    }    printf("\n");        return 0;}

高精度乘法

高精度乘法计算原理

  在读小学时,我们做乘法都采用竖式方法,如图 1 所示。 这样,我们可以写出两个整数相减的算法。

编辑

  我们就可以用 C++ 语言来模拟这个竖式减法的过程。我们可以考虑利用 C++ 的数组来存储对应数据,假设用数组 A 存储被减数 856 的每一位,具体来说就是 A1 存储个位 6,A2 存储十位 5,A3存储百位 8;类似数组 A 的结构,使用数组 B 存储减数 25;类似数组 A 的结构,使用数组 C 来存储对应的乘积 21400。两数相加的结果就如图 2 所示。这样理论上来说,我们就可以计算无限大的数据。如上图 2 所示,下表表示对应的存储方式。

数组 A数组 B数组 C
[0]650
[1]520
[2]84
[3]1
[4]2

  如上面的图 2 ,首先计算被乘数与乘数的个位数字的乘积,把结果保存到积数组中,然后再用被除数乘以乘数的十位数字,把结果退一位加到积数组中。每加一次乘积结果就进行一次进位处理,放在一个新组数里面。其方法与加法中的进位处理一样。 

编辑

关键点

1、a[i]*b[j] 应该累加到 i+j 的位置;

2、累加总结果为: c[i+j] = a[i]*b[j]+jw+c[i+j];

3、所以每次累加完后:

      1)带入下一位累加的进位: jw = c[i+j] / 10;

      2)本位实际数: c[i+j] %= 10。

高精度乘法实现

思路

1、定义存储数组。

2、读入数据处理。

3、从个位开始模拟竖式乘法的过程,完成整个乘法。

4、删除前导 0 。所谓前导零,就是出现类似这样数据 01234,这个 0 实际是不需要的。

5、输出结果。倒序输出减法的结果数组 C,因为我们的个位是存储在下标为 0 的地方。

技术细节说明

定义存储数组

根据题目的要求定义数组。这个部分代码如下

 
const int MAXN = 1e5+4; //根据题目的最大值。+4为了防止A+B出现进位char s1[MAXN] = {};//存储字符串char s2[MAXN] = {};//存储字符串int a[MAXN] = {};//存储加数Aint b[MAXN] = {};//存储加数Bint c[2*MAXN] = {};//存储乘积
 

读入数据并处理

这里我们先考虑以下几种情况,即 -3*5=-15 或者 -4*8=-32 或者 -3*(-2)=6,也就是说,需要对输入数据的正负号进行判断。这个部分代码如下:

    scanf("%s %s", s1, s2);//读入字符串     //处理负数    bool flaga = false;//乘数a的符号    if ('-'==s1[0]) {        flaga = true;        strcpy(s1, &s1[1]);//删除负号    }    bool flagb = false;//乘数b的符号    if ('-'==s2[0]) {        flagb = true;        strcpy(s2, &s2[1]);//删除负号    }     //处理输出的负号    if ((true==flaga && false==flagb) || (false==flaga && true==flagb)) {        printf("-");    }     //处理乘数1    int lena = strlen(s1);    for (int i=0; i<lena; i++) {        a[lena-i-1]=s1[i]-'0';    }     //处理乘数2    int lenb = strlen(s2);    for (int i=0; i<lenb; i++) {        b[lenb-i-1]=s2[i]-'0';    }

模拟竖式乘法

这个部分代码如下:

    //模拟竖式乘法    int jw;//上一轮计算进位    for (int i=0; i<lena; i++) {        jw=0;        for (int j=0; j<lenb; j++) {            //交叉乘积            c[i+j] = a[i]*b[j]+jw+c[i+j];//当前乘积+上次乘积进位+原数            jw = c[i+j]/10;//处理进位            c[i+j] %= 10;        }        c[i+lenb]=jw;//进位设置    }

删除前导零

这个部分代码如下:

    //删除前导零    int lenc=lena+lenb;    for (int i=lenc-1; i>=0; i--) {        //因为我们是从索引 0 开始,所以最高位是保存在 len-1        if (0==c[i] && lenc>1) {            //注意要有 lenc>1 这个条件。考虑特殊情况,加法结果为 00,我们实际要输出 0。            lenc--;        } else {            //第一个不是零的最高位,结束删除            break;        }    }

输出计算结果

采用倒序的方式输出,因为我们数据保存是倒序结构,也就是低位在前。

    //逆序打印输出    for (int i=lenc-1; i>=0; i--) {        printf("%d", c[i]);    }    printf("\n");

高精度乘法代码:

 
#include <bits/stdc++.h>using namespace std; const int MAXN = 200+4; //根据题目的最大值。+4为了防止A+B出现进位char s1[MAXN] = {};//存储字符串char s2[MAXN] = {};//存储字符串int a[MAXN] = {};//存储加数Aint b[MAXN] = {};//存储加数Bint c[2*MAXN] = {};//存储和B int main() {    scanf("%s %s", s1, s2);//读入字符串     //处理负数    bool flaga = false;//乘数a的符号    if ('-'==s1[0]) {        flaga = true;        strcpy(s1, &s1[1]);//删除负号    }    bool flagb = false;//乘数b的符号    if ('-'==s2[0]) {        flagb = true;        strcpy(s2, &s2[1]);//删除负号    }     //处理输出的负号    if ((true==flaga && false==flagb) || (false==flaga && true==flagb)) {        printf("-");    }     //处理乘数1    int lena = strlen(s1);    for (int i=0; i<lena; i++) {        a[lena-i-1]=s1[i]-'0';    }     //处理乘数2    int lenb = strlen(s2);    for (int i=0; i<lenb; i++) {        b[lenb-i-1]=s2[i]-'0';    }        //模拟竖式乘法    int jw;//上一轮计算进位    for (int i=0; i<lena; i++) {        jw=0;        for (int j=0; j<lenb; j++) {            //交叉乘积            c[i+j] = a[i]*b[j]+jw+c[i+j];//当前乘积+上次乘积进位+原数            jw = c[i+j]/10;//处理进位            c[i+j] %= 10;        }        c[i+lenb]=jw;//进位设置    }     //删除前导零    int lenc=lena+lenb;    for (int i=lenc-1; i>=0; i--) {        //因为我们是从索引 0 开始,所以最高位是保存在 len-1        if (0==c[i] && lenc>1) {            //注意要有 lenc>1 这个条件。考虑特殊情况,加法结果为 00,我们实际要输出 0。            lenc--;        } else {            //第一个不是零的最高位,结束删除            break;        }    }            //逆序打印输出    for (int i=lenc-1; i>=0; i--) {        printf("%d", c[i]);    }    printf("\n");     return 0;}

高精度除法

高精度除法计算原理

在读小学时,我们做除法都采用竖式方法计算。被除数从高位开始,和除数对齐,逐位“试商”,“试商”后除数减去“试商”的数的乘积,如下图所示。

编辑

采用计算机做高精度除法时,模拟日常除法的步骤。但计算机不可能做“试商”,这时,我们可以采用减法来模拟。

试商过程

1、将除数移动和被除数对齐,位数不够时,补 0。

2、利用被除数减去除数,一直减到被除数小于除数,减的次数,就是“试商”的结果,每移动一次。

3、重复上述步骤,一直到被除数和除数的位数相等为止。

举例说明

举一个例子,比如 524134 除以 123,结果是 4261 ,余数为 31。

1、第一位 4 的来源是我们把 524 和 123 对齐,然后进行循环减法,循环了 4 次,余 32;

2、将 32134 的前三位 321 继续和 123 对齐,循环减法 2 次,余 75;

3、把 7534 的前三位 753 和 123 对齐,循环减法 6 次,余 15;

4、将 154 和 123 对齐,只能减 1 次,余 31。

所以 524134 除以 123,结果是 4261,余数为 31。

计算过程

AB余数
1524134123432
20321340123275
300753400123615
4000154000123131
5000031000012331

高精度除法实现

思路

1、定义存储数组。

2、读入数据处理。

3、试商过程。

4、删除前导 0 。所谓前导零,就是出现类似这样数据 01234,这个 0 实际是不需要的。

5、输出结果。倒序输出减法的结果数组 C,因为我们的个位是存储在下标为 0 的地方。

技术细节说明

定义存储数组

根据题目的要求定义数组。这个部分代码如下:

 
const int MAXN = 1e5+4; //根据题目的最大值。+4为了防止A+B出现进位char s1[MAXN] = {};//存储字符串char s2[MAXN] = {};//存储字符串int a[MAXN] = {};//存储被除数int b[MAXN] = {};//存储除数Bint c[MAXN] = {};//存储商int tmp[MAXN] = {};

注意:这里的数组索引 0 所在的数据表示本数据的长度。

辅助函数

比较大小函数

用于比较两个 int 类型数组内数据大小。返回值和 C++ 库函数 campare() 相同。

 
int compare(int a[], int b[]) {    //索引为0的数据为数组长度    if (a[0]>b[0]) {        return 1;    } else if (a[0]<b[0]) {        return -1;    }     //逐位比较    for (int i=a[0]; i>0; i--) {        if (a[i]>b[i]) {            return 1;        } else if (a[i]<b[i]) {            return -1;        }    }     return 0;}

移位操作函数

 
void numcpy(int a[],int b[],int dest) {    //将数组右移,使两个数组右端对齐,形参q数组储存右移后的结果    for (int i=1;i<=a[0];i++) {        b[i+dest-1] =a[i];    }    b[0] = a[0]+dest-1;}

读入数据并处理

这里我们先考虑以下几种情况,即 15/4=3 ... 3、-8/3=-2 ... -2、10/(-3)=-3 ... 1 或者 -3/(-2)=1 ... -1,也就是说,需要对输入数据的正负号进行判断。这个部分代码如下:

    scanf("%s %s", s1, s2);//读入字符串     //处理负数    bool flaga = false;//乘数a的符号    if ('-'==s1[0]) {        flaga = true;        strcpy(s1, &s1[1]);//删除负号    }    bool flagb = false;//乘数b的符号    if ('-'==s2[0]) {        flagb = true;        strcpy(s2, &s2[1]);//删除负号    }     //处理输出的负号    if (true==flaga && false==flagb) {        //商为负数        printf("-");    }     //处理乘数1    int len = strlen(s1);    a[0] = len;    for (int i=0; i<len; i++) {        a[len-i]=s1[i]-'0';    }     //处理乘数2    len = strlen(s2);    b[0] = len;    for (int i=0; i<len; i++) {        b[len-i]=s2[i]-'0';    }

试商

这个部分代码如下:

    if (0==compare(a,b)) {        //两数相等        printf("1\n0\n");        return 0;    } else if (-1==compare(a,b)) {        //被除数小,除数大        printf("0\n");//输出除数        if (true==flaga) {            printf("-");        }        printf("%s\n", s1);        return 0;    } else {        c[0] = a[0]-b[0]+1;        for (int i=c[0]; i>0; i--) {            memset(tmp, 0, sizeof(tmp));            //高位对齐            numcpy(b,tmp,i);             //            while (compare(a, tmp)>=0) {                c[i]++;                //减法                for (int j=1; j<=a[0]; j++) {                    if (a[j]<tmp[j]) {                        a[j+1]--;                        a[j]+=10;                    }                    a[j]-=tmp[j];                }                 int k=a[0];                while (a[k]==0) {                    k--;                }                a[0]=k;            }        }         //控制最高位的0        while (c[0]>0 && c[c[0]]==0) {            c[0]--;        }    }

输出计算结果

采用倒序的方式输出,因为我们数据保存是倒序结构,也就是倒着排的

    //逆序打印输出商和余数    for (int i=c[0]; i>0; i--) {        printf("%d", c[i]);    }    printf("\n");    if (0==a[0]) {        printf("0\n");    } else {        if (true==flaga) {            printf("-");        }        for (int i=a[0]; i>0; i--) {            printf("%d", a[i]);        }        printf("\n");    }

输出格式需要根据实际题目要求进行修改。

高精度除法:

 
#include <bits/stdc++.h>using namespace std; const int MAXN = 300+4; //根据题目的最大值。+4为了防止A+B出现进位char s1[MAXN] = {};//存储字符串char s2[MAXN] = {};//存储字符串int tmp[MAXN] = {};//交换用字符串int a[MAXN] = {};//存储加数Aint b[MAXN] = {};//存储加数Bint c[MAXN] = {};//存储和B int compare(int a[], int b[]) {    //索引为0的数据为数组长度    if (a[0]>b[0]) {        return 1;    } else if (a[0]<b[0]) {        return -1;    }     //逐位比较    for (int i=a[0]; i>0; i--) {        if (a[i]>b[i]) {            return 1;        } else if (a[i]<b[i]) {            return -1;        }    }     return 0;} void numcpy(int a[],int b[],int dest) {    //将数组右移,使两个数组右端对齐,形参q数组储存右移后的结果    for (int i=1;i<=a[0];i++) {        b[i+dest-1] =a[i];    }    b[0] = a[0]+dest-1;} int main() {    scanf("%s %s", s1, s2);//读入字符串     //处理负数    bool flaga = false;//乘数a的符号    if ('-'==s1[0]) {        flaga = true;        strcpy(s1, &s1[1]);//删除负号    }    bool flagb = false;//乘数b的符号    if ('-'==s2[0]) {        flagb = true;        strcpy(s2, &s2[1]);//删除负号    }     //处理输出的负号    if (true==flaga && false==flagb) {        //商为负数        printf("-");    }     //处理乘数1    int len = strlen(s1);    a[0] = len;    for (int i=0; i<len; i++) {        a[len-i]=s1[i]-'0';    }     //处理乘数2    len = strlen(s2);    b[0] = len;    for (int i=0; i<len; i++) {        b[len-i]=s2[i]-'0';    }     if (0==compare(a,b)) {        //两数相等        printf("1\n0\n");        return 0;    } else if (-1==compare(a,b)) {        //被除数小,除数大        printf("0\n");//输出除数        if (true==flaga) {            printf("-");        }        printf("%s\n", s1);        return 0;    } else {        c[0] = a[0]-b[0]+1;        for (int i=c[0]; i>0; i--) {            memset(tmp, 0, sizeof(tmp));            //高位对齐            numcpy(b,tmp,i);             //            while (compare(a, tmp)>=0) {                c[i]++;                //减法                for (int j=1; j<=a[0]; j++) {                    if (a[j]<tmp[j]) {                        a[j+1]--;                        a[j]+=10;                    }                    a[j]-=tmp[j];                }                 int k=a[0];                while (a[k]==0) {                    k--;                }                a[0]=k;            }        }         //控制最高位的0        while (c[0]>0 && c[c[0]]==0) {            c[0]--;        }    }     //逆序打印输出商和余数    for (int i=c[0]; i>0; i--) {        printf("%d", c[i]);    }    printf("\n");    if (0==a[0]) {        printf("0\n");    } else {        if (true==flaga) {            printf("-");        }        for (int i=a[0]; i>0; i--) {            printf("%d", a[i]);        }        printf("\n");    }    return 0;}

  我们高精度算法的最基本篇“加减乘除”已经完结,后期给大家讲高精度根号等等…… 

  • 4
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

龙星尘

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值