高精度加法(C++实现)

高精度加法

简介

用于计算含有超过一般变量存放不下的非负整数

高精度加法这个过程是模拟的小学竖式加法计算

步骤

以下有顺序之分

  • 数组清零
  • 输入
  • 获取长度
  • 逆置
  • 字符型数字转成对应的整型数字
  • 计算并输出

简单来看重要的步骤也就以下几步

  • 清零
  • 逆置
  • 转换
  • 相加计算(包含进位)

代码实现

逆置

因为数组存放的元素顺序与我们计算的顺序是相反的,在竖式计算中我们是将其右对齐(个位对个位,十位对十位,以此类推),而读取数字后的两个数组是左对齐的,因此我们要将里面的元素逆置

//参数:需要逆置的数组,数组长度
void invertElem(char s[], unsigned long n)
{
    unsigned long len = n - 1;
    for (int i = 0, j = len; i < j; i++, j--)
    {
        char temp = s[i];
        s[i] = s[j];
        s[j] = temp;
    }

}

转换

为了方便计算和进位,我们需要将字符型的数字转化成实际数字

注意:这里的转换不是类型转换,例如字符类型8,我们要让它自减48,转化成ASCII码为8的对应的字符,存放元素的数组的类型并没有改变

转换必须在逆置之后。如果转换在前逆置在后,则逆置时分不清末尾的0是数字的一部分还是结束符转换后的数字

//参数:数组,长度
void charInt(char s[], unsigned long n)
{
    for (int i = 0; i < n; i++)
        s[i] -= 48;
}

相加

有了以上两个函数之后,我们就可以进行相加了,这里不多说,分析都在注释里,所以直接上代码

int main()
{
    while (1)
    {
        char a[1024];
        char b[1024];
        char c[2049];

        //这里必须将每一个元素都置为0,否则位数不同的数字相加时会乱掉
        memset(a, 0, sizeof(a));
        memset(b, 0, sizeof(b));
        memset(c, 0, sizeof(c));

        scanf("%s", a);
        scanf("%s", b);

        //长度获取要在转换之前
        unsigned long len_a = strlen(a);
        unsigned long len_b = strlen(b);

        unsigned long max_len = len_a > len_b ? len_a : len_b;

        //逆置
        invertElem(a, len_a);
        invertElem(b, len_b);

        //转换
        charInt(a, len_a);
        charInt(b, len_b);

        int carry = 0; //进位

        //相加,核心步骤
        //这里的i必须能取到max_len,最高位计算式可能会向前进一位
        //比如99+1,原本最多两位,相加后得到了一个三位数
        for (int i = 0; i <= max_len; i++)
        {
            c[i] = (carry + a[i] + b[i]) % 10;
            carry = (carry + a[i] + b[i]) / 10;
        }

        int i;
        //寻找第一个不为0的数字或全是0的情况况下找到最后一个0
        //这是为了防止00+0之类的特殊情况,在这种情况发生时确保只输出一个0
        for (i = max_len; i >= 1 && c[i] == 0; i--);

        for (; i >= 0; i--)
            printf("%d", c[i]);
        printf("\n");

    }


    return 0;
}

完整代码

#include <iostream>
#include <string.h>
#include <math.h>

using namespace std;
//参数:需要逆置的数组,数组长度
void invertElem(char s[], unsigned long n)
{
    unsigned long len = n - 1;
    for (int i = 0, j = len; i < j; i++, j--)
    {
        char temp = s[i];
        s[i] = s[j];
        s[j] = temp;
    }

}

void charInt(char s[], unsigned long n)
{
    for (int i = 0; i < n; i++)
        s[i] -= 48;
}

int main()
{
    while (1)
    {
        char a[1024];
        char b[1024];
        char c[2049];

        //这里必须将每一个元素都置为0,否则位数不同的数字相加时会乱掉
        memset(a, 0, sizeof(a));
        memset(b, 0, sizeof(b));
        memset(c, 0, sizeof(c));

        scanf("%s", a);
        scanf("%s", b);

        //长度获取要在转换之前
        unsigned long len_a = strlen(a);
        unsigned long len_b = strlen(b);

        unsigned long max_len = len_a > len_b ? len_a : len_b;

        //逆置
        invertElem(a, len_a);
        invertElem(b, len_b);

        //转换
        charInt(a, len_a);
        charInt(b, len_b);

        int carry = 0; //进位

        //相加,核心步骤
        //这里的i必须能取到max_len,最高位计算式可能会向前进一位
        //比如99+1,原本最多两位,相加后得到了一个三位数
        for (int i = 0; i <= max_len; i++)
        {
            c[i] = (carry + a[i] + b[i]) % 10;
            carry = (carry + a[i] + b[i]) / 10;
        }

        int i;
        //寻找第一个不为0的数字或全是0的情况况下找到最后一个0
        //这是为了防止00+0之类的特殊情况,在这种情况发生时确保只输出一个0
        for (i = max_len; i >= 1 && c[i] == 0; i--);

        for (; i >= 0; i--)
            printf("%d", c[i]);
        printf("\n");

    }


    return 0;
}

推荐阅读更多精彩内容

  • 概述 当计算的数值非常大或是对于计算的精度要求非常高时,用已知的数据类型无法精确地表示数值。可以采用数组来模拟大数...
    咸鱼爱学习阅读 426评论 1 0
  • 高精度加法的实现原理: 高精,用一个数组或者字符串来记录每一位是数字几,用另一个变量来记录有几位,输出时一般要倒着...
    追随清居的誓言阅读 132评论 0 0
  • 之前早就想把学过的算法记录下来,但是一直没有时间。最近在给五年级的小学生上OI的算法课,所以正好可以把所思所想留存...
    flydan阅读 619评论 0 0
  • 高精度计算 有时候C语言内置数据类型难以处理非常大的整数计算,此时需要自己实现大整数计算。 数字存储方式 一般的高...
    yuq329阅读 138评论 0 1
  • 高精度数的加法 什么是高精度数? 高精度数是指一种数据范围超过long long 的数。 题目描述 求两个不超过2...
    朱红_fc5d阅读 1,630评论 1 16
  • 高精度计算主要思想是:把巨大无比无法直接计算的数以字符串的形式读入转化成数字按位存入数组(倒着存入)依照竖式计算的...
    zeppoe阅读 342评论 0 0
  • 高精度加法: 1.字符串读入2.字符串转数组3.竖式加法4.消前导05.倒序输出intlong long 10^1...
    大地蛋阅读 115评论 0 0
  • 四种类型高精度算法[仅对C++而言] 1.A+B:两个大整数(A和B的位数为10^6)相加 a.利用数组存储大整数...
    CurryCoder阅读 279评论 0 1
  • 之所以需要高精度加法,是因为已有的数据类型不足以满足加数和被加数的存储。为了解决数据太长的问题,最核心的思想就是使...
    秋木丘阅读 98评论 0 0
  • 本文内容为练习LeetCode题目时的解题思路和不同算法的记录,实现语言为C++,代码保存在Github,均已在L...
    SK木眠阅读 771评论 0 0
  • 1.大整数加法:开两队数组,输入为字符串,然后要转换成int数组。最先输入的是char[0]的位置,然而这个应该是...
    nino天阅读 342评论 0 2
  • Java在java.math包中提供的API类BigDecimal,用来对超过16位有效位的数进行精确的运算。双精...
    Angelicas阅读 2,518评论 0 20
  • 问题描述输入两个整数a和b,输出这两个整数的和。a和b都不超过100位。算法描述由于a和b都比较大,所以不能直接使...
    就这样吧嘞阅读 249评论 1 1
  • 问题描述 输入两个整数a和b,输出这两个整数的和。a和b都不超过100位。 算法描述 由于a和b都比较大,所以不能...
    冒泡泡de可乐阅读 92评论 0 0
  • C++入门必做题 题目 共76道题 以下是C++入门必做题所有题目,共76道题 关于字体显示的说明: 由于字体格式...
    平面嘟嘟阅读 946评论 0 0
  • Substrate的transaction-payment模块分析 transaction-payment模块提供...
    建怀阅读 7,440评论 0 4
  • 16宿命:用概率思维提高你的胜算 以前的我是风险厌恶者,不喜欢去冒险,但是人生放弃了冒险,也就放弃了无数的可能。 ...
    yichen大刀阅读 5,305评论 0 4
  • 公元:2019年11月28日19时42分农历:二零一九年 十一月 初三日 戌时干支:己亥乙亥己巳甲戌当月节气:立冬...
    石放阅读 6,366评论 0 2
  • 想要快速入门CAD,对于零基础的新手来说的确有一定的困难。不过只要你掌握了以下这些CAD快速入门技巧,你就跨进了C...
    努力的王榆阅读 2,620评论 0 3
  • 昨天考过了阿里规范,心里舒坦了好多,敲代码也犹如神助。早早完成工作回家喽
    常亚星阅读 2,729评论 0 1