前几天我在我的代码库中添加了一个分数类(第一次,以前从来没有需要过分数类,我怀疑我现在做了什么,但到底是怎么回事…)。在写两个分数之间的加法时,我发现了一个小的优化,但它没有意义(从数学意义上说),为什么它是这样的。
为了说明这一点,我将使用分数A和B,有效地分别由a、bn、ad和bd组成分子和分母。
这里有两个用于gcd/lcm的函数,公式也在维基百科上。它们很简单,很容易理解。当然,LCM也可以是(A*B)/C。
static unsigned int GreatestCommonDivisor(unsigned int A, unsigned int B)
{
return (!B) ? A : GreatestCommonDivisor(B, A % B);
}
static unsigned int LeastCommonMultiple(unsigned int A, unsigned int B)
{
const unsigned int gcDivisor = GreatestCommonDivisor(A, B);
return (A / gcDivisor) * B;
}
首先,我们来看看第一种方法:
least_common_mul = least_common_multiple(Ad, Bd)
new_nominator = An * (least_common_mul / Ad) + Bn * (least_common_mul / Bd)
new_denominator = least_common_mul
瞧,工作,显而易见,完成了。
然后通过在记事本上的一些涂鸦,我发现了另一个有效的方法:
greatest_common_div = greatest_common_divisor(Ad, Bd)
den_quot_a = Ad / greatest_common_div
den_quot_b = Bd / greatest_common_div
new_numerator = An * den_quot_b + Bn * den_quot_a
new_denominator = den_quot_a * Bd
现在,新的分母是相当明显的,因为它与LCD功能中的分母完全相同。其他的似乎也很有意义,除了交换了与原始分子相乘的正确因子,在这一行是具体的:
new_numerator = An * den_quot_b + Bn * den_quot_a
为什么不是
A+B
B?
输入示例:5/12和11/18
greatest_common_div = 6
den_quot_a = 12/6 = 2;
den_quot_b = 18/6 = 3;
new_numerator = 5*3 + 11*2 = 37;
new_denominator = 36;