本题中操作的注意点挺多

主要的思想是,将小数部分和整数部分分开来,然后再对齐

随后进行多位全加器的计算

最后要注意最后一位,进位与否,要进行分支选择

注意点:使用strchr函数的时候,一定要注意,返回的是一个指针,如果要得到其数组标号则要跟数组首地址相减!!!

/**
 * @file Float_Add.cpp
 * @brief 实现浮点数的加法
 * @remarks
 * 1将一个浮点数,拆分成整数和小数部分
 * 2然后将整数反向录入后补齐;小数部分,正向录入后补齐,再反过来
 * 3将整数/小数部分,相加后,再翻转过来
 * 4输出时,要判断整数最终是否进位,再行输出
 */
#include <stdio.h>
#include <string.h>
#include <math.h>
#define MAX 101

//分割时,要保证让整数直接反向录入
//小数则是正向录入
void FRAC(char ForAdd[], char IntPart[], char DeciPart[])
{
    int i = 0, j = 0;
    int PointPos = (strchr(ForAdd, '.') - ForAdd);
    for (i = PointPos + 1; i < strlen(ForAdd); i++)
        DeciPart[j++] = ForAdd[i];
    DeciPart[j] = '\0';
    j = 0;
    for (int k = PointPos - 1; k >= 0; k--)
        IntPart[k] = ForAdd[j++];
    IntPart[i] = '\0';
}

void DeciAlign(char DeciPart1[], char DeciPart2[])
{
    int L1 = strlen(DeciPart1), L2 = strlen(DeciPart2);
    int Max_L = (L1 > L2) ? L1 : L2;
    if (L1 >= L2)
    {
        for (int i = L2; i < L1; i++)
            DeciPart2[i] = '0';
        DeciPart2[L1] = '\0';
    }
    else
    {
        for (int i = L1; i < L2; i++)
            DeciPart1[i] = '0';
        DeciPart1[L2] = '\0';
    }
    char TMP[MAX] = {0};
    for (int k = 0; k < Max_L; k++)
    {
        TMP[k] = DeciPart1[Max_L - 1 - k];
    }
    strcpy(DeciPart1, TMP);
    for (int k = 0; k < Max_L; k++)
    {
        TMP[k] = DeciPart2[Max_L - 1 - k];
    }
    strcpy(DeciPart2, TMP);
}

void IntAlign(char IntPart1[], char IntPart2[])
{
    int L1 = strlen(IntPart1), L2 = strlen(IntPart2);
    if (L1 >= L2)
    {
        for (int i = L2; i < L1; i++)
            IntPart2[i] = '0';
        IntPart2[L1] = '\0';
    }
    else
    {
        for (int i = L1; i < L2; i++)
            IntPart1[i] = '0';
        IntPart1[L2] = '\0';
    }
}

//将所有数据相加,并且逆转过来,并且将进位存入Carry中
int MultiSum(char Part1[], char Part2[], int Carry)
{
    int L = strlen(Part1);
    int i = 0, tmp;
    while (i < L)
    {
        tmp = Carry + Part1[i] + Part2[i] - 2 * '0';
        Part2[i] = tmp % 10 + '0';
        Carry = tmp / 10;
        i++;
    }
    for (int i = L - 1; i >= 0; i--)
        Part1[L - i - 1] = Part2[i];
    return Carry;
}

int main()
{
    //用于保存浮点数
    char ForAdd1[MAX] = {0};
    char ForAdd2[MAX] = {0};
    while (fgets(ForAdd1, MAX, stdin))
    {
        //用于存放两个浮点数的整形和小数部分
        char IntPart1[MAX] = {0};
        char IntPart2[MAX] = {0};
        char DeciPart1[MAX] = {0};
        char DeciPart2[MAX] = {0};
        ForAdd1[strlen(ForAdd1) - 1] = '\0';
        fgets(ForAdd2, MAX, stdin);
        ForAdd2[strlen(ForAdd2) - 1] = '\0';

        FRAC(ForAdd1, IntPart1, DeciPart1);
        FRAC(ForAdd2, IntPart2, DeciPart2);
        DeciAlign(DeciPart1, DeciPart2);
        IntAlign(IntPart1, IntPart2);

        int Carry = 0;
        Carry = MultiSum(DeciPart1, DeciPart2, Carry);
        Carry = MultiSum(IntPart1, IntPart2, Carry);
        if (!Carry)
            printf("%s.%s\n", IntPart1, DeciPart1);
        else
            printf("%d%s.%s\n", Carry, IntPart1, DeciPart1);
    }
    return 0;
}