本题中操作的注意点挺多
主要的思想是,将小数部分和整数部分分开来,然后再对齐
随后进行多位全加器的计算
最后要注意最后一位,进位与否,要进行分支选择
注意点:使用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;
}