您的位置:首页 > 其它

两个超大整数求和。控制台输入两个30位以内超大整数,且其中至少有一个数大于18446744073709551615,程序能将两个数相加的结果输出。

2018-07-29 00:41 846 查看

// lzy 2018.7.29 于东北大学

//仅代表东北大学最低编程水平,才疏学浅,欢迎各位参考指摘!
//定义了一个BigNumber类,用于存放超大数(大于long long double)
//此代码用于30位以内数字相加,可根据需要修改参数

#include "stdafx.h"
#include "stdio.h"
#include <iostream>
#include <cstdlib>
using namespace std;

//定义了BigNumber类
class BigNumber
{
public:
    BigNumber();
    ~BigNumber();
    void ShowNum();
    void InputNum();
    int Length();
    friend BigNumber Add(BigNumber a, BigNumber b);
private:
    char s[40];
};


//构造函数
BigNumber::BigNumber()
{
    cout << "Constructor has been called." << endl;
    int i;
    for (i = 0; i < 40; i++)
        s[i] = '0';
}

//析构函数
BigNumber::~BigNumber()
{
    cout << endl << " Deconstructor has been called." << endl;
}

//输入数据
void BigNumber::InputNum()
{
    int i;
    for (i = 29; i >= 0 && s[i + 1] != '\n'; i--)
        scanf_s("%c", &s[i]);
    s[i+1] = '0';
}

//求数字长度并返回长度
int BigNumber::Length()
{
    int loc = 0;
    while (s[loc] == '0')
        loc++;
    loc = 29 - loc;
    return loc + 1;
}

//向屏幕输出数据
void BigNumber::ShowNum()
{
    int i;
    if (Length() == 0)
        cout << "0" << endl;
    else
    for (i = 29; i > 29 - Length(); i--)
        cout << s[i];

}

//定义了取两数较大数的函数,也可利用库函数
int max(int a, int b)
{
    if (a >= b) return a;
    return b;
}

//加法运算
BigNumber Add(BigNumber a, BigNumber b)
{
    int temp = 0, i, m, n, length = max(a.Length(), b.Length());
    int move = abs(a.Length() - b.Length());
    //将a,b的长度都存入了一个新的变量,因为后面操作可能会改变Length()的返回值
    int aa = a.Length();
    int bb = b.Length();
    //将数字从个位向高位依次对其
    //a长度大于b,移动b中元素
    if (a.Length() > b.Length())
    {
        int times = b.Length();
        for (n = 0; n < times; n++)
            b.s[30 - times - move + n] = b.s[30 - times + n];
        for (int m = 30 - move; m < 30; m++)
            b.s[m] = '0';
    }
    //a长度小于b,移动a中元素
    else if (a.Length() < b.Length())
    {
        int times = a.Length();
        for (n = 0; n < times; n++)
            a.s[30 - times - move + n] = a.s[30 - times + n];
        for (int m = 30 - move; m < 30; m++)
            a.s[m] = '0';
    }
    //创建一个新的BigNumber用于存储结果
    BigNumber c;
    //从最低位开始加法运算
    for (i = 29 - length; i <= 29; i++)
    {
        if (temp == 1)//进位
            c.s[i] = (a.s[i] - 48) + (b.s[i] - 48) + 1;
        else //不进位
            c.s[i] = (a.s[i] - 48) + (b.s[i] - 48);
        if (c.s[i] > 9)//如果本位相加结果大于9,利用temp控制进位(temp == 1时)
        {
            if (i == 29)//最高位相加进位,造成假上溢,再开辟一位,取值1
            {
                c.s[i] = c.s[i] % 10;
                c.s[30] = 1;
            }
            else
            {
                c.s[i] = c.s[i] % 10;
                temp = 1;//temp用于确定下一次加法运算位(高位)是否有进位
            }
        }
        else temp = 0;
    }

    if (c.s[30] == 1)//假上溢情况发生,输出比原来较长的数还多一位
    {
        for (i = 30; i > 30 - c.Length(); i--)
            cout << char(c.s[i] + 48);
    }
    else
    {
        for (i = 29; i > 30 - c.Length(); i--)
            cout << char(c.s[i] + 48);
    }
    return c;

}

int _tmain(int argc, _TCHAR* argv[])
{
    BigNumber a, b;
    a.InputNum();
    b.InputNum();

    Add(a, b);
    system("pause");
    return 0;
}

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐