大数加减法(C++实现)

以下是我写大数类的头文件,cpp文件,说明文档等,代码可用,但限于笔者自身水平,也有诸多不足之处,有待日后改善。不过程序是没有问题的,可以计算大数的加减乘运算。
readme.md :
程序名:BigNumPlus
程序功能:此程序针对任意整实数的加减乘运算,支持负值的计算。
程序文件: BigNum.h //定义大数类
BigNum.cpp //实现大数的各种运算功能
main.cpp //测试文件
程序的实现思路:
大数存储方式是通过一个int bignum[]数组实现的,数组下标对应数的位数。并增加了
len 和 sign成员表示大数的数值总位数 和 符号位。
程序是通过 成员函数TurnStringtoNum 将string 类型的字符串转化位大数的类型并存储。
整个大数的加减乘运算,是以10进制的逢10进1,不够借1的原则编写的。

程序缺点:
1、没有实现动态的内存分配,造成大量的内存浪费。
2、没有实现除法的运算。
3、没有实现输入输出流的重载。
4、以10进制的形式储存程序好空间大,且效率低。
程序优点:
1、实现了符号支持,即可以负值运算。
2、实现了+、-、*的重载。
3、实现了加减乘的运算。
4、以10进制的形式储存程序,运算思路简单,程序代码好理解。
BigNum.h:

#ifndef BIGNUM_H
#define BIGNUM_H

#include <iostream>
#include<string>
#include<ctype.h>
using namespace std;
#define Max_Size 500  //最大的位数控制
#define Max(a,b) len>b.len?len:b.len//a,b中长度较大的
//此类是大数类,用以实现任意整数之间加减乘的运算
class BigNum
{
    public:
        BigNum();
        virtual ~BigNum();
        //此函数是将string类型的数据转换成数组储存
        bool TurnStringtoNum(string a);
        //赋值运算符重载
        BigNum operator=( BigNum other);
        //此函数用来判断两个大数绝对值的大小
        bool operator>=(BigNum b);
        //此函数是实现大数的加法算法
        BigNum  operator+(BigNum b);
        //此函数是实现大数的减法
        BigNum operator-(BigNum b);
        //此函数是实现大数的乘法
        BigNum operator*(BigNum b);
        //此函数用来打印大数
        void PrintAll();
    private:
    //定义大数的数据组织方式
    int bignum[Max_Size];  //最大控制之内的数值存储方式
    int len;         //数值长度
    char sign;     //符号位
};

#endif // BIGNUM_H

BigNum.cpp:

#include "BigNum.h"
//构造函数,初始化各个数据成员
BigNum::BigNum()
{
    for(int i=0;i<Max_Size;i++)
    {
        bignum[i]=0;
    }
    len=0;
    sign='+';//ctor
}
//析构函数
BigNum::~BigNum()
{
    //dtor
}
//此函数是将string类型的数据转换成数组储存
bool  BigNum::TurnStringtoNum(string a){
    //有符号时
      if((a[0]=='+')||(a[0]=='-')){
            sign=a[0];
      for(int i=1;i<(signed)a.size();i++)
      {
        //判断输入的是否为数值
        if(!isdigit(a[i])){
        cout<<"对不起,你输入的不是数值"<<endl;
        return false;
        }
      }
      for(int i=0;i<Max_Size;i++)bignum[i]=0;
         len=a.size()-1;
      for(int k=0;k<(signed)a.size()-1;k++)
      {
        bignum[a.size()-k-2]=a[k+1]-48;//将大数以数组的方式储存,并实现位数与下标对应
      }
      return true;
      }
//无符号时默认符号位为+
     else if(isdigit(a[0])){
            sign='+';
      //判断是否为数值
          for(int i=0;i<(signed)a.size();i++)
      {
        //判断输入的是否为数值
        if(!isdigit(a[i])){
        cout<<"对不起,你输入的不是数值"<<endl;
        return false;
        }
      }
      //字符串转化为大数
       for(int i=0;i<Max_Size;i++)bignum[i]=0;
      len=a.size();
      for(int k=0;k<(signed)a.size();k++)
      {
        bignum[a.size()-k-1]=a[k]-48;//将大数以数组的方式储存,并实现位数与下标对应
      }
      return true;
      }
      //判断符号是否正确
      else {cout<<"对不起,你可能+、-号输错了!"<<endl;return false;}
    return false;
}
//判断a,b的数值的绝对值的大小
bool BigNum::operator>=(BigNum b){
    //当a的长度大于b的长度时
    if(len>b.len)return true;
    //当a的长度等于b的长度时
    else if(len==b.len){
            int i=0;
        for( i=0;i<len;i++){
            if(bignum[len-i-1]==b.bignum[b.len-i-1])continue;
            if(bignum[len-i-1]>b.bignum[b.len-i-1])return true;
            if(bignum[len-i-1]<b.bignum[b.len-i-1])return false;
        }
        if(i==len)return true;
    }
    //当a的长度小于b的长度时
    else return false;
    return false;
}

//此函数是实现大数的加法算法
BigNum  BigNum::operator+(BigNum b){
    BigNum result;
//第一种情况
     if((sign=='-' && b.sign=='-')||(sign=='+' && b.sign=='+'))
    {
        if(sign=='-')result.sign='-';
        else result.sign='+';
        int Msize=Max(a,b);//找到a,b中长度较大的
        result.len=Msize+1;//初始化
        for(int j=0;j<Msize+1;j++)
        {

        result.bignum[j]=result.bignum[j]+bignum[j]+b.bignum[j];
        //若加和后大于等于10则进位
        if(result.bignum[j]>=10)
        {
        result.bignum[j]=result.bignum[j]-10;
        result.bignum[j+1]=result.bignum[j+1]+1;
        }
        //否则不进
        else{
            result.bignum[j]=result.bignum[j];
        }
        }
        return result;
    }
//第二种情况
    if((sign=='-' && b.sign=='+')||(sign=='+' && b.sign=='-'))
    {
        int Msize=Max(a,b);//找到a,b中长度较大的
        result.len=Msize+1;
        //分两种情况,1、a>=b 2、a<=b
        //1
        if((*this)>=b){
                result.sign=sign;
             for(int j=0;j<Msize+1;j++)
        {
            result.bignum[j]=result.bignum[j]+bignum[j]-b.bignum[j];
            //若减后小于0则需借位
            if(result.bignum[j]<0)
            {
                result.bignum[j]=result.bignum[j]+10;
                result.bignum[j+1]=result.bignum[j+1]-1;
            }
            //否则不借
            else{
                result.bignum[j]=result.bignum[j];
            }
        }
        }
        //2
        if(b>=(*this)){
            result.sign=b.sign;
            for(int j=0;j<Msize+1;j++)
        {
            result.bignum[j]=result.bignum[j]+b.bignum[j]-bignum[j];
            //同上
            if(result.bignum[j]<0)
            {
                result.bignum[j]=result.bignum[j]+10;
                result.bignum[j+1]=result.bignum[j+1]-1;
            }
            else{
                result.bignum[j]=result.bignum[j];
            }
        }
        }
        return result;
    }

    return result;
}
//此函数是实现大数的减法
 BigNum BigNum::operator-(BigNum b)
 {
        BigNum result;
//第一种情况
     if((sign=='-' && b.sign=='-')||(sign=='+' && b.sign=='+'))
    {
         int Msize=Max(a,b);//找到a,b中长度较大的
        result.len=Msize+1;
        if((*this)>=b){
                if(sign=='-')result.sign='-';
                else result.sign='+';
                result.sign=sign;
             for(int j=0;j<Msize+1;j++)
        {
            result.bignum[j]=result.bignum[j]+bignum[j]-b.bignum[j];
            if(result.bignum[j]<0)
            {
                result.bignum[j]=result.bignum[j]+10;
                result.bignum[j+1]=result.bignum[j+1]-1;
            }
            else{
                result.bignum[j]=result.bignum[j];
            }
        }
        }
        if(b>=(*this)){
            if(sign=='-')result.sign='+';
            else result.sign='-';
            for(int j=0;j<Msize+1;j++)
        {
            result.bignum[j]=result.bignum[j]+b.bignum[j]-bignum[j];
            if(result.bignum[j]<0)
            {
                result.bignum[j]=result.bignum[j]+10;
                result.bignum[j+1]=result.bignum[j+1]-1;
            }
            else{
                result.bignum[j]=result.bignum[j];
            }
        }
        }
    return result;
    }

//第二种情况
    if((sign=='-' && b.sign=='+')||(sign=='+' && b.sign=='-'))
    {
        if(sign=='-')result.sign='-';
        else result.sign='+';
        int Msize=Max(a,b);//找到a,b中长度较大的
        result.len=Msize+1;//初始化
        for(int j=0;j<Msize+1;j++)
        {

        result.bignum[j]=result.bignum[j]+bignum[j]+b.bignum[j];
        if(result.bignum[j]>=10)
        {
        result.bignum[j]=result.bignum[j]-10;
        result.bignum[j+1]=result.bignum[j+1]+1;
        }
        else{
            result.bignum[j]=result.bignum[j];
        }
        }
        return result;
    }
    return result;
 }

 //此函数是实现大数的乘法
 BigNum  BigNum::operator*(BigNum b){
    BigNum result;
    int Msize=(len+1)*b.len+1;
    result.len=Msize;
    //同号为正,异号为负
    if((sign=='-' && b.sign=='-')||(sign=='+' && b.sign=='+'))result.sign='+';
    if((sign=='-' && b.sign=='+')||(sign=='+' && b.sign=='-'))result.sign='-';
    int i,j;//循环控制变量
    //申请临时空间以存放每层数值
    BigNum *temp=new BigNum[b.len];
    for(i=0;i<b.len;i++){
    for(j=0;j<len;j++){
            //b的各个位依次乘以a的值
        temp[i].bignum[j+i]=b.bignum[i]*bignum[j]+temp[i].bignum[j+i];
    //乘积小与10则不进位
        if(temp[i].bignum[j+i]<10){
                temp[i].bignum[j+i]=temp[i].bignum[j+i];
        }
        //否则进位
        else {
            temp[i].bignum[j+i+1]=temp[i].bignum[j+i]/10;
            temp[i].bignum[j+i]=temp[i].bignum[j+i]%10;
        }
    }
    //将每层累加
    temp[i].sign=result.sign;
    result=result+temp[i];
}
delete temp;  //释放内存
 return result;
 }
//赋值运算符重载
BigNum BigNum::operator= (BigNum other)
{
    for(int i=0;i<other.len;i++){
        this->bignum[i]=other.bignum[i];
    }
    this->len=other.len;
    this->sign=other.sign;
    return *this;
}
//此函数用来打印大数
void BigNum::PrintAll(){
    //输出符号位
    cout<<sign;
    //找到大数前有几个无用的零,并控制其输出
    int nu=0;
    for(int i=len-1;i>=0;i--)
    {
        if(bignum[i]==0){nu++;continue;}
        else break;
    }
    if(nu==len)cout<<"0"<<endl;
    else{
        for(int t=0;t<len-nu;t++){
        cout<<bignum[len-t-1-nu];
    }
    cout<<endl;
    }

}

main.cpp:

#include <iostream>
#include"BigNum.h"
using namespace std;
int main()
{
    //a,b为操作数值,r为结果数值
    BigNum a,b,r;
    string A,B;
    cout<<"请输入两个任意500位之内的实整数(正负均可):"<<endl;
    cin>>A>>B;
    if(a.TurnStringtoNum(A)&&b.TurnStringtoNum(B))
    {
        int order=0;

        cout<<"你想让这两个数做什么运算?输入命令前的数字:"<<endl;
        cout<<"1、加法"<<endl<<"2、减法"<<endl;
        cout<<"3、乘法"<<endl;
        cin>>order;
        if(order==1)r=a+b;
        if(order==2)r=a-b;
        if(order==3)r=a*b;
        cout<<"结果为:"<<endl;
        r.PrintAll();
    }

    return 0;
}

首先,我们要搞清楚大数的储存方法,我这里是开了一个数组bignum[Max_Size]来存放大数,即从下标0开始,向前存放大数的每一位上的数值,我们知道每一位上的数不可能超过10,所以每位就是0~9,另外还要封装len,表示数值的位数(方便操作),还要符号位sign定义大数的符号正负。TurnStringtoNum函数是将String类型的输入数据转化为大数储存。另外,大数的加法是通过逢10进1的思路实现,减法通过不够10借1实现。代码有注释,不在重复赘述。这里说下乘法,我们知道乘法列竖式计算时,是下面的乘数从个位开始与上面的乘数相乘,且得到的数错位相加得到的。依照这个思路,我们要另外开临时的数组来储存这些需要错位相加的数,具体算法看代码。这里提供几个比较好的博客:
http://blog.csdn.net/hackbuteer1/article/details/6595881
http://blog.csdn.net/dvt777/article/details/48897225
http://blog.csdn.net/snow_5288/article/details/71079692?locationNum=2&fps=1

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

angelavor

觉得有收获,给我个三连吧

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

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

打赏作者

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

抵扣说明:

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

余额充值