1922 Problem C 浮点数加法

1 篇文章 0 订阅
1 篇文章 0 订阅

题目描述
求2个浮点数相加的和
题目中输入输出中出现浮点数都有如下的形式:
P1P2…Pi.Q1Q2…Qj
对于整数部分,P1P2…Pi是一个非负整数
对于小数部分,Qj不等于0

输入
对于每组案例,第1行是测试数据的组数n,每组测试数据占2行,分别是两个加数。
每组测试数据之间有一个空行,每行数据不超过100个字符

输出
每组案例是n行,每组测试数据有一行输出是相应的和。
输出保证一定是一个小数部分不为0的浮点数

样例输入

2
3.756
90.564

4543.5435
43.25

样例输出

94.32
4586.7935

非常暴力地搞出来了,主要思路就是将两个小数都分整数部分和小数部分考虑,首先进行两个小数部分的相加,如果位数不同,比如25和3000这样的,那么将位数小的那个也即25变成2500,来和3000相加,相加之后记录最高位的进位,再将这个进位考虑的同时进行整数部分的相加,最后输出小数部分的时候先进行末尾0的去除,去除之后再进行输出。

#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
struct bign{
    int d[1010];
    int len;
    bign()
    {
        memset(d, 0, sizeof(d));
        len = 0;
    }
};
int carry_to_d = 0;
bign change(char a[])
{
    bign c;
    c.len = strlen(a);
    for(int i = 0 ; i < c.len ; ++i)
    {
        c.d[i] = a[c.len - i - 1] - '0';
    }
    return c;
}
void print1(bign c)
{
    for(int i = c.len - 1 ; i >= 0 ; i--)
        printf("%d", c.d[i]);
}
void print2(bign c)
{
    int a[5000], index = 0;
    int flag = 0;
    for(int i = 0 ; i < c.len ; i++)
    {
        if(c.d[i] != 0 && !flag) //去除小数末尾的0
        {
            flag = 1;
        }
        if(flag)
            a[index++] = c.d[i];
    }
    for(int i = index - 1 ; i >= 0 ; i--)
        printf("%d", a[i]);
}
bign add(bign a, bign b, int carry, int on)
{
    bign c;
    for(int i = 0 ; i < a.len || i < b.len ; ++i)
    {
        int tmp = a.d[i] + b.d[i] + carry;
        c.d[c.len++] = tmp % 10;
        carry = tmp / 10;
    }
    if(carry != 0)
    {
        if(on == 1) //如果是整数部分在相加,那么就保存进位,如果是小数部分相加,将进位转交给整数,本身不保留此进位
        c.d[c.len++] = carry;
        carry_to_d = carry;
    }
    return c;
}
int main()
{
    int n;
    char str1d[1010], str2d[1010], str1f[1010], str2f[1010], str1[1010], str2[1010];
    while(scanf("%d", &n) != EOF)
    {
        for(int j = 0 ; j < n ; ++j)
        {
            carry_to_d = 0;
        scanf("%s%s", str1, str2);
        int i;
        for(i = 0 ; str1[i] != '.' ; ++i)
            str1d[i] = str1[i];
            str1d[i] = '\0';
        i++;
            int index = 0; //分整数小数两部分读入
        for(; str1[i] ; ++i)
        {
            str1f[index++] = str1[i];
        }
            int max = index;
            str1f[index] = '\0';
        for(i = 0 ; str2[i] != '.' ; ++i)
            str2d[i] = str2[i];
            str2d[i] = '\0';
        i++;
            index = 0;
        for(; str2[i] ; ++i)
            str2f[index++] = str2[i];
            str2f[index] = '\0';
            if(index > max)
            {
                for(; max < index ; ++max)
                    str1f[max] = '0'; //保证小数部分位数相同,如25和3000,将25变成2500,再进行相加
                str1f[max] = '\0';
            }
            else if(index < max)
            {
                for(; index < max ; ++index)
                    str2f[index] = '0';
                str2f[index] = '\0';
            }
       // printf("%s %s %s %s\n", str1d, str1f, str2d, str2f);
        getchar();
        bign ad = change(str1d);
        bign bd = change(str2d);
        bign af = change(str1f);
        bign bf = change(str2f);
        bign tmp = add(af, bf, 0, 0); //先安排一次小数部分相加,得到进到整数部分的进位
        print1(add(ad, bd, carry_to_d, 1)); //将小数部分进上来的进位考虑到整数部分的加法过程中
        printf(".");
        print2(add(af, bf, 0, 0)); //输出小数部分
        printf("\n");
        }
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值