《算法笔记》中,对于大整数的运算,给出了最基础的几个算法模板,包括大整数的结构体、输出、与字符串的转换,以及四则预算(不包含高精度与高精度的乘除)。但是在codeup训练当中,又出现了两种经典问题,第一是对大浮点数的处理,第二是对于大整数的进制转换问题。这篇文章主要讲解大浮点数的加减运算。
codeup相关题型对应标号为:(看完文章就可以试试)直接在csdn搜也可以搜到原题
1922-Problem-C-浮点数加法
对于大浮点数,可以创建如下的一个结构体:
struct floatn{
int x[1000];
int y[1000];//小数储存低位在数组高位,跟字符数组一样
int px;
int py;
floatn(){
memset(x,0,sizeof(x));
memset(y,0,sizeof(y));
px = 0;
py = 0;
}
};
其中,为了方便对于小数部分的保存,将小数部分的高位存放在数组低位(与整数部分相反,与字符数组相同),得到大浮点数的结构体之后,开始想办法把字符串转换为浮点数存储在这个结构体当中,大体思路如下:
定义一个布尔类型的flag,记录目前存储的状态(是正在处理整数部分还是处理小数部分呢?)然后对整个字符数组进行遍历,如果flag为真,就让整数部分的px++,flag为假,说明,目前正在处理小数部分,而由于小数部分的存储顺序与字符数组一致,就直接写:
a.y[a.py++]=str[i]-’0’;最后再统一利用《算法笔记》中的大整数的change函数的思路,对整数部分处理,此时,a.px的值等价于change函数中的a.len,具体代码如下:
floatn change(char str[])
{
floatn a;
int len=strlen(str);
bool flag=true;//标记正在处理的是小数部分还是整数部分
for(int i=0;i
之后,开始研究让两个大浮点数相加的函数实现:
从后往前,先处理小数,从小数的低位开始相加,思路与普通的大整数相加思路差不多,然后再加整数部分就行了。只要整数的学会,这里看懂就很轻松:
在小数相加时候注意,由于小数相加是从数组最高位开始,所以一开始就直接把小数中的py赋值为加数和被加数中py最大的那一个,相加完之后,消去小数部分末位的0即可:
注意max函数在头文件algorithm当中哦
floatn add(floatn a,floatn b)
{
floatn c;
c.py=max(a.py,b.py);
int carry=0;
for(int i=c.py-1;i>=0;i--)
{
int temp=carry+a.y[i]+b.y[i];
c.y[i]=temp%10;
carry=temp/10;
}
while(c.y[c.py-1]==0) c.py--;//消除小数末位的0 很容易忽略!!!!!
carry=(a.y[0]+b.y[0]+carry)/10;
for(int i=0;i
从浮点数加法和大整数减法的思路可以得出浮点数减法的函数实现如下:
floatn sub(floatn a,floatn b)
{
floatn c;
c.py=max(a.py,b.py);
int flag=0;
for(int i=c.py-1;i>=0;i--)
{
if(a.y[i]
最后就是打印这个大浮点数,不多说了:
void show(floatn a)
{
for(int i=a.px-1;i>=0;i--)
printf("%d",a.x[i]);
printf(".");
for(int i=0;i
写出主函数,测试一下:
int main(){
int n;
while(cin>>n){
getchar();
while(n--){
char str1[1000];
char str2[1000];
scanf("%s%s",str1,str2);
floatn z1;
floatn z2;
floatn x = change(str1);
floatn y = change(str2);
z1 = sub(x,y);
z2=add(x,y);
show(z1);
show(z2);
cout<