大数加法

大数加法

Content

   引言

  可行代码

  自定义函数简介

  写在最后

引言

想必readers都学过加法吧!(没学过就去小学一年级预习一下,哈哈哈)。例如:1 + 1 = 2 有手就行。

之前经过学习我们得知,int可以储存-2^31~~2^31的数,long long、double呢?话不多说,自己查。那么int最大也就只能存储9位数的样子,如果遇到大型数据计算,例如:112233445566778899 + 998877665544332211 就......没办法了吧。

此处我们引进大数加法,其核心思想是利用字符数组来模拟数字(把单个数字存入数组,用整个数组表示一个数字,真好懂!),之后,拿起小学学的进位加法知识愉快的写代码吧!写完就可以骄傲的说,我会用编程写加法了,真不错!

温馨提示:可行代码中函数不懂还有函数简介辅助哦 !

可行代码

 

#include <iostream>
#include <string.h>
using namespace std;

void invert(char *restr, char *wrstr);       // 数字倒序函数
void addtion(char *number1, char *number2);  // 加法函数
void reverse_putstr(char *charstr);          // 反向输出数组内数据函数
const int N = 1005;                          //最大位数控制
int up, temp;                                //up为记录进位变量, temp记录和(看后文)
char first_num[N], second_num[N], buffer[N]; // 分别为第一个数字倒序,第二个数字倒序,输入数据载体(正序)

void invert(char *restr, char *wrstr) // 数字倒序函数
{                                     // restr读入正序数组, wrstr待写入的逆序数组
    for (int i = 0, j = strlen(restr) - 1; j >= 0; j--)
    {
        wrstr[i++] = restr[j] - '0'; // 字符'1'的ASCII码是48,减去'0'便于运算
    }
    return;
}

void addtion(char *number1, char *number2) // 加法函数
{
    for (int i = 0, up = 0; i < N; i++)
    {
        temp = number1[i] + number2[i] + up;
        number1[i] = temp % 10; // 取得个位数
        up = temp / 10;         // 取得十位数以进位
    }
}

void reverse_putstr(char *charstr) // 反向输出数组内数据函数
{
    bool sign[N]; // 做标记的数组,true表示当前位置是有效数位,否则不是
    int position;
    memset(sign, false, N);
    for (int i = 0; i < N; i++) // 此循环的目的是为了找出结果中最后一位有效数位
    {
        if (charstr[i] + '0' > '0')
            for (int j = 0; j <= i; j++)
            {
                sign[j] = true;
                position = i;
            }
    }
    for (int i = position; i >= 0; i--)
    {
        printf("%c", charstr[i] + '0'); // 由于invert()函数执行时first_num内被减去了'0',此处加上
    }
    return;
}

int main()
{
    while (1)
    {
        memset(first_num, 0, N), memset(second_num, 0, N); // 初始化数组为0
        cin >> buffer;
        getchar(); // 清空缓冲区
        invert(buffer, first_num);
        cin >> buffer;
        getchar();
        invert(buffer, second_num);
        addtion(first_num, second_num);
        reverse_putstr(first_num);
        cout << endl;
    }
    return 0;
}

 

 

自定义函数简介

写代码注意要点是进位问题,我们使用addtion() 函数计算。temp很好的记录两个加数的和,up可以记录是否进位。但是在进位的过程中会有一个缺憾,就是首位数字有个能是个0(例如first_num = {5},second_num = {5} 经过addtion() 函数处理会是first_num = {0, 1}第一个0便成为了结束符),会导致此0作为字符串结束标识符,以至于无法输出。此问题交给revese_putstr() 解决。

由于计算要从个位计算,我们应该将数字倒序存储,我们使用invert() 函数反转字符串。invert() 函数中不仅仅将数字倒序,还要注意我们将字符的ASCII码做了一个转换,为何转换?—— 字符 '1' + '1' == 48 + 48 == 96 == '`' 无法达到目的。 

此外我们还要得到一个正向的result,所以要反向输出,我们使用reverse_putstr() 函数。addtion() 函数介绍中的 5 + 5 问题,为了找到第二位中的 1 我们用做标记的方法实现,sign数组会不断的被第二重循环更新,同时也会记录下最新位置。最后就可以实现反向输出啦,nice。

自定义函数只是为了简化主函数,使思路更急清晰,建议多使用。

写在最后

大数加法只是大数模拟、高精度的冰山一角,还有很大的空间值得探索,各位reader编程路上更加fighting哦 ! 假使reader有什么问题欢迎联系Kirk,Kirk一定会尽力帮忙的。如果想练习这样的题来检验自己也记得私信Kirk啦,还有发现文章有问题、bug也记得和Kirk谈谈哦!

原文地址:https://www.cnblogs.com/kirk-notes/p/14294942.html