ΣSyaoran
【自己的课设作品】大数计算问题

本帖最后由 ΣSyaoran 于 2012-7-10 02:36 编辑

RT,是c++的课程设计,就拿上来晒晒了……

有啥高手建议的话还请提出~~~

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

#include "stdafx.h" //若为Visual C++ 6.0编译环境请删除此语句
#include *本站禁止HTML标签噢*
#include *本站禁止HTML标签噢*
#include *本站禁止HTML标签噢*
using namespacestd;

/*class Ex_number;
Ex_number operator +(Ex_number a,Ex_number b); //若为Visual C++ 6.0编译环境请保留此段语句
Ex_number operator -(Ex_number a,Ex_number b);*/
class Ex_number //所要求的大数类
{
public:
Ex_number(string ori_num) //利用构造函数对大数进行初步处理
{
ori_num_len=ori_num.length()+1; //这里加一是为后面可能产生的进位预留空间
num=newint[ori_num_len]; //将字符串型的大数转换为整形数组
num[0]=0; //首位作为进位预留位定义为0,并在后面的循环录入中被跳过
for(i=1;i<ori_num_len;i++)
{
if(ori_num.at(i-1)>=48&&ori_num.at(i-1)<=57) //输入数据审查
{
num=ori_num.at(i-1)-48; //数据无误,则录入进数组
w=1;
}
else
{
w=0; //数据有误,变量更改值,供主函数识别
break;
}
}
}
boolw; //数据审查变量,由于要在主函数调用,故设置为公用项
voiddisplay(); //大数输出函数
voidup(int i); //进位函数声明
voiddown(int i); //退位函数声明
friendEx_number operator +(Ex_numbera,Ex_number b); //友元加法函数重载
friendEx_number operator -(Ex_numbera,Ex_number b); //友元减法函数重载
private:
string ori_num; //字符串型大数变量
intori_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==0)
continue;
else
break;
}
elseif(i==ori_num_len)
{
cout<<"0"; //全部是“0”,即结果为0的处理
}
else
break;
}
for(;i<ori_num_len;i++) //省略了起始条件,即i仍为前值,接着继续循环
{
cout<<num;
}
cout<<endl;
}
void Ex_number::up(inti) //进位函数
{
for(intn=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(inti) //退位函数,和进位函数异曲同工~
{
for(intn=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) //加法运算符重载
{
inti;
intj=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+b.num[j]>=10) //判断是否进位
{
a.num=a.num+b.num[j]-10; //本位的处理
a.up(i); //调用进位函数,对i之前的数据元素进行进位操作
}
else
{
a.num=a.num+b.num[j];
}
j--; //j作为副循环条件,以满足整个循环的顺利进行
}
returna;
}

Ex_number operator -(Ex_number a,Ex_number b) //依旧异曲同工~
{
inti;
intj=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<b.num[j])
{
a.num=10+a.num-b.num[j];
a.down(i);
}
else
{
a.num=a.num-b.num[j];
}
j--;
}
returna;
}

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;
charc,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(!(num1.w==0||num2.w==0)) //判断数据是否有误
{
if(c=='+') //执行相应的操作
{
cout<<'=';
(num1+num2).display();
}
elseif(c=='-')
{
cout<<'='<<d;
(num1-num2).display();
}
else
{
cout<<"非加减操作,请重新输入表达式"<<endl;
}
}
else
{
cout<<"数据有误,请重新输入!"<<endl;
}
system("pause");
}
return0;
}

貌似不能加附件,就懒得上程序了~以上~~~~

gwl3323405
果然底层啊
展开Biu

果然底层啊,有点烦但很有趣的样子。

[查看全文]
Ekino
个有效位数的浮点运算够用的实用主义者飘过
展开Biu

表示7,8个有效位数的浮点运算够用的实用主义者飘过……

[查看全文]
轻舟过
来说问题不大
展开Biu

CyberZHG 发表于 2012-7-12 22:02

对于ACM来说问题不大,反正Java给3倍时间~~

主要就是用着方便

如果有三倍时限那还好

[查看全文]
CyberZHG
都封装好了
展开Biu

轻舟过 发表于 2012-7-12 19:36

Java都封装好了,不过Java的速度是问题

对于ACM来说问题不大,反正Java给3倍时间~~

主要就是用着方便

[查看全文]
轻舟过
表示遇到大数就用
展开Biu

CyberZHG 发表于 2012-7-12 18:42

身为ACMer表示遇到大数就用Java的BigInteger。

大数感觉还是用记录10^5以内的数的int数组比较快。 ...

Java都封装好了,不过Java的速度是问题

[查看全文]
CyberZHG
表示遇到大数就用
展开Biu

身为ACMer表示遇到大数就用Java的BigInteger。

大数感觉还是用记录10^5以内的数的int数组比较快。

[查看全文]
轻舟过
本帖最后由
展开Biu

本帖最后由 轻舟过 于 2012-7-10 14:03 编辑

加减法实现起来不是特别难,不过LZ能写出来并封装起来还是不错

大数的乘法难一些,然后除法更难

[查看全文]
面瘫大明神
不撸个乘除法么
展开Biu

不撸个乘除法么

[查看全文]