本篇博文BGM:《TSUBASA·翼》OST:break the sword of justice~我就是在这首曲子下完成最后的调试的~~

4.大数计算问题
设计要求:大数是超过整数表示范围的整数,针对正整数运算,定义一个大数类,并编写两个大数类对象的加法和减法函数。
基本要求:
(1)编写大数类对象的构造函数和输入输出函数
(2)编写大数类对象的加法和减法运算函数
(3)设计主函数时,可指定测试数据。

       以上就是我这组的C++课程设计的课题,在开始动手前,觉得这程序应该比较简单,因为只要求了加减法。后来百度一下大数的介绍,说这个和密码学还有很多科学计算都有关系,于是当时还想干脆一口气把乘法、幂计算都写了算了,不过后来继续百度又知道,其实有个公司出了一个专门的类库,支持“任意精度的数学运算”,所以我想“可能到我需要用计算机进行大数计算的时候,早就用那个类库,而不是自己写了吧。”于是便打消了这个念头。不过对于第三点“可指定测试数据”,我表示“略为不屑”,因为“指定测试数据”其实是给题目降难度,而且这样做只会使程序“例程化”,而无任何实际价值可言,所以大家等会可以看到,我的程序虽然确实只能做加减法,不过还是算比较人性化、实用化的。

       其实这题目的思路很明了,先将输入的大数作为字符串保存,然后转换为整形数组,再利用指针对数组进行相关操作。然后再把相应的东西包装成类就完事了。不过就结果而言,写这程序所耗费的时间还是略微超出了我的预计(一天半,我本来想一天应该就可以完事的)。现在看来,这程序已经是我写的最长的程序了(166行),东西一多自然要顾及的变量就多,一不小心自己的逻辑就混乱了。所以我写着写着实在找不到问题出在哪,就去玩玩游戏、吃吃饭,然后继续~我之所以如此坚持的原因在于,我自己给自己的评价就是如此:”若把这个程序写出来了,C++考试的分数也就没多少所谓了,给自己也有个交代。”故,“本程序100%原创手打~”而回过头来看,循环、判断、字符串处理、数组、指针、自定义函数、类、友元、重载……C++这本书里除了继承(因为不需要子类嘛~)基本都有了~满足感还是挺高的~

       虽然我知道估计没人会看我接下来要贴的代码,不过我还是自作多情地写了些注释~明天找个时间写下报告,应该不会太费事~PS:之前说的一笔画程序应该还是要写的,只要我别一直懒下去,最近准备强制提高自己的行动点了……
PS:已知问题,我在新建数组空间后没有删除,貌似对程序运行没啥大碍,于是就懒掉了……

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

class Ex_number                                           //所要求的大数类
{
public:
Ex_number(string ori_num)                             //利用构造函数对大数进行初步处理
{
ori_num_len=ori_num.length()+1;                   //这里加一是为后面可能产生的进位预留空间
num=new int[ori_num_len];                         //将字符串型的大数转换为整形数组
num[0]=0;                                         //首位作为进位预留位定义为0,并在后面的循环录入中被跳过
for(i=1;i<ori_num_len;i++)
num[i]=ori_num.at(i-1)-48;
}
void display();                                        //大数输出函数
void up(int i);                                        //进位函数声明
void down(int i);                                      //退位函数声明
friend Ex_number operator +(Ex_number a,Ex_number b);  //友元加法函数重载
friend Ex_number operator -(Ex_number a,Ex_number b);  //友元减法函数重载
private:
string ori_num;                                        //字符串型大数变量
int ori_num_len,i;                                     //辅助变量(字符串长度变量与字符位置变量)
int *num;                                              //数组指针

};
void Ex_number::display()
{
for(i=0;i<ori_num_len;i++)                              //对于数组采用典型的循环结构输出
{
if(i<ori_num_len-1)                                 //对于若数据开头是“0”的处理
{
if(num[i]==0)
continue;
else
break;
}
else
{
cout<<"0";                                       //全部是“0”,即结果为0的处理
}
}
for(;i<ori_num_len;i++)                                  //省略了起始条件,即i仍为前值,接着继续循环
{
cout<<num[i];
}
cout<<endl;
}
void Ex_number::up(int i)                                    //进位函数     
{
for(int n=1;n<=i;n++)                                    //函数主体是一个循环,原理大家都懂~
{
if(num[i-n]<9)
{
num[i-n]++;
break;
}
else
{
num[i-n]=num[i-n]-9;
continue;                                         //这里的“continue”应该可以省略,这里全为了代码整齐(而增加了代码量)
}
}
}
void Ex_number::down(int i)                                    //退位函数,和进位函数异曲同工~
{
for(int n=1;n<=i;n++)
{
if(num[i-n]>0)
{
num[i-n]--;
break;
}
else
{
num[i-n]=9;
continue;
}
}

}
Ex_number operator +(Ex_number a,Ex_number b)                  //加法运算符重载
{
int i;
int j=b.ori_num_len-1;                                     //这里的“-1”是考虑到了前面为了进位而增加的元素
for(i=a.ori_num_len-1;i>a.ori_num_len-b.ori_num_len;i--)   //我们计算是直接对于a进行更改的,所以以i为循环条件
{
if(a.num[i]+b.num[j]>=10)                              //判断是否进位
{
a.num[i]=a.num[i]+b.num[j]-10;                      //本位的处理
a.up(i);                                            //调用进位函数,对i之前的数据元素进行进位操作
}
else
{
a.num[i]=a.num[i]+b.num[j];
}
j--;                                                     //j作为副循环条件,以满足整个循环的顺利进行
}
return a;
}

Ex_number operator -(Ex_number a,Ex_number b)                     //依旧异曲同工~
{
int i;
int j=b.ori_num_len-1;
for(i=a.ori_num_len-1;i>a.ori_num_len-b.ori_num_len;i--)
{
if(a.num[i]<b.num[j])
{
a.num[i]=10+a.num[i]-b.num[j];
a.down(i);
}
else
{
a.num[i]=a.num[i]-b.num[j];
}
j--;
}
return a;
}
void welcome(void)                                                        //介绍
{
cout<<"~~~~~~~~~~~~程序说明~~~~~~~~~~~"<<endl;
cout<<"1.本程序可以实现两任意位正整数的加减运算。"<<endl;
cout<<"2.请先输入第一个整数,回车后输入加或减号与第二个整数。"<<endl;
cout<<"☆例,输入:"<<endl;
cout<<"  99999999↙"<<endl;
cout<<"  +1↙"<<endl;
}
int main()
{
welcome();
while(1)                                                             //死循环,这样每次计算就不用关闭程序重新开了
{
string a,b,temp;
char c,d;
cin>>a>>c>>b;                                                    //暂时想到的比较简单又人性化的输入方法
if(a.length()<b.length())                                        //保证大数作为(被加数)循环变量
{
temp=a;
a=b;
b=temp;
d='-';                                                       //判断正负号
}
else
{
d=' ';
}
Ex_number num1(a);                                               //这里就开始调用构造函数进行数据处理了
Ex_number num2(b);
if(c=='+')                                                       //执行相应的操作
{
cout<<'=';
(num1+num2).display();
}
else if(c=='-')
{
cout<<'='<<d;
(num1-num2).display();
}
system("pause");
}
return 0; 
}

 

图片