《编程思维与实践》1060.浮点数加法

《编程思维与实践》1060.浮点数加法

题目

在这里插入图片描述

思路

浮点数可以分为[整数部分].[小数部分],可以将两个部分分开处理,最后再合并,但在处理四舍五入时较为繁琐,

为了方便起见,这里采用将两个部分一起处理的方式:

在这里插入图片描述
由于浮点数不超过500位:整数部分最多500位,小数部分最多500位,

所以加法后的结果整数部分最多501位,小数部分最多500位.

所以可以宏定义L=500,数组最大长度为2L+1,其中[0,L]存整数部分,[L+1,2L+1]存小数部分;

具体步骤:

用结构体存浮点数,cnt存整数部分位数.

1.读取浮点数:

①有小数点:找到小数点的位置,小数点前逆向遍历存取整数部分,小数点后正向遍历存取小数部分;

②无小数点(遍历到字符串末尾):从字符串末尾逆向遍历存整数部分.

2.浮点数加法:

先将保留位(N位)后的部分相加,进位后判断保留位的后一位是四舍还是五入;

再将保留位和前面的部分相加,最后进行进位.

3.输出浮点数,整数部分根据位数输出,补一个小数点后再输出小数部分到保留位即可.

注意的点:

1.(坑)测试数据中,两个大整数可能含有前置0,所以在读取时计算整数位数需要去除前置0;

2.加法在进位时需要判断是否要多一位.

代码

#include<stdio.h>
#include<stdlib.h> 
#include<string.h>
#define L 500

typedef struct{int cnt,v[2*L+1];}FLOAT;  //cnt这里存的是整数位数

FLOAT carry(FLOAT S,int bin);   //进位 bin表示进制 binary
FLOAT Input();   //input a float number
FLOAT add(FLOAT S,FLOAT T,int N); //顺序加
void output(FLOAT A,int N); //输出

int main()
{
	FLOAT A=Input();
	FLOAT B=Input();
    int N;
	scanf("%d",&N);
	FLOAT ans=add(A,B,N); 	
	output(ans,N);
	return 0;
}

FLOAT carry(FLOAT S,int bin)   //进位 bin表示进制 binary
{
	int flag=0;
	for(int i=2*L;i>=L-S.cnt+1;i--)   //顺序存 进位需要逆着进行
	{
		int temp=S.v[i]+flag;
		S.v[i]=temp%bin;
		flag=temp/bin;
	}
	if(flag)   //判断是否要进一位
	{
		S.cnt++;
		S.v[L-S.cnt+1]=flag;
	} 
	return S;
}

FLOAT Input()   //input a float number
{
    char s[L+1];
    scanf("%s",s);  
    FLOAT A={0,{0}};
    int i=0;
    while(i<strlen(s)&&s[i]!='.') //无小数点和有小数点的情况都包含
	{
		i++; 	//定位小数点
	}
	if(i==0)
	{
		A.cnt++;  //整数部分为0 
	}
    for(int j=i-1,k=L;j>=0;j--) 
    {
        A.cnt++;
    	A.v[k--]=s[j]-'0';  //整数部分 
	}
    for(int j=i+1,k=L+1;j<strlen(s);j++) 
    {
    	A.v[k++]=s[j]-'0';   //小数部分
	}
	for(int i=L-A.cnt+1;i<L&&A.v[i]==0;i++)   //去除读入内容的前置0
	{
		A.cnt--;
	}
    return A;
}

FLOAT add(FLOAT S,FLOAT T,int N) //顺序加
{   
	int max=S.cnt>T.cnt?S.cnt:T.cnt;
    FLOAT R={max,{0}};
	int i;
    for(i=2*L;i>=0;i--)
    {
        R.v[i]=S.v[i]+T.v[i];
    }
    R=carry(R,10);
    if(R.v[L+N+1]>=5)  //保留位的下一位
    {
    	R.v[L+N]++;  //四舍五入 
	}
    R=carry(R,10);
    return R;
}

void output(FLOAT A,int N)
{
    for(int i=L-A.cnt+1;i<=L+N;i++)
    {
        if(i==L+1)
        {
            printf(".");
        }
        printf("%d",A.v[i]);
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值