在C语言的学习过程中,我们发现大多的小数(double, float)因采用二进制的存储方式,会有精度丢失的问题,若再进行更多的运算,则精度丢失更加严重。对于一个强迫症程序员来说,这种精度丢失的问题想想就会觉得难受,因而,我想到了用结构体存储分数来进行运算,这样在有理数范围内,若想要小数的表达结果,那么只有最后一步有精度丢失,话不多说,直接上代码:
定义分数结构
// 定义分数
typedef struct
{
int numerator=0; // 分子
int denominator=1; // 分母
} fraction;
在定义分数结构的时候,我们将分子初始化为0,分母初始化为1,这样就可以使分式的值为0且有意义。
辗转相除法
// 辗转相除法
int gcd(int m, int n)
{
int t;
while (t = m % n)
{
m = n;
n = t;
}
return n;
}
由于分数在运算过程中难免会产生分子分母出现公因子的情况,所以引入辗转相除函数进行约分。(gcd有很多的博主已经介绍过,这里不多赘述)。
约分
// 约分
fraction reducefraction(fraction a)
{
int divisor = gcd(a.numerator, a.denominator);
a.numerator /= divisor, a.denominator /= divisor;
if (a.numerator > 0 && a.denominator < 0)
a.numerator = -a.numerator, a.denominator = -a.denominator;
return a;
}
(divisor为因子的意思,这里取分子分母的最大公约数。)进行约分的过程中可能会出现分母为负数但分子为正数的情况,这对于数值计算来说可能没有什么影响,但是如果题目对输出格式有要求,那这样可能导致无法AC。当然,如果你不想在这里设if使每次gcd都跑