该函数应该比较存储在两个结构中的两个分数。
以下是我现在的代码:
int compare_fractions(Fraction L, Fraction R)
{
double z = (L.numer/L.denom) - (R.numer/R.denom);
// THIS CODE IS INCORRECT - FIX IT!
if(z == 0)
return 0;
else if(z < 0)
return -1;
else if(z
return 1;
}
然而,当我运行以下测试时,我收到0并进行以下比较:
(1,3) ? (2,3)
(5,6) ? (3,4)
(2,4) ? (1,4)
其中(1,3)是馏分L,(2,3)是馏分R
答案 0 :(得分:2)
如果分子和分母是int
s(或其他整数类型),那么除法是integer division,你将永远得不到正确的小数部分
将其投射到double
可以解决大部分问题,但是您将面临缓慢的划分,有时会因浮点舍入而出现错误。
你应该使用乘法。它会更快,你不需要浮点除法,这在一些架构上非常慢。这样您就不必担心浮点比较了
int compare_fractions(Fraction L, Fraction R)
{
int z = L.numer*R.denom - L.denom*R.numer;
if (z == 0)
return 0;
else if (z > 0)
return 1;
else
return -1;
}
当然你需要确保所有分母都是正数,否则你需要对它进行标准化(你可以使用下面的chux建议)。如果您可以通过更广泛的类型(如
)进行数学计算,那么您还需要考虑溢出long long z = (long long)L.numer*R.denom - L.denom*R.numer
如果您可以稍微松懈要求以返回负值,0或正值小于,等于或大于strcmp()
的情况,那么您可以完全删除对z的值的检查{{1}直接改为
如果你仍然需要返回-1,0和1,那么有几种方法可以缩短/优化它,如
return L.numer*R.denom - L.denom*R.numer
答案 1 :(得分:0)
当您将int
除以另一个int
时,它将首先将它们分开并且(因为结果必须是int
)将结果舍入为零。首先,它被投射到double
:
int a = 7;
int b = 3;
double c = a / b; // = 2, because 2.333... rounded down is 2, which is
// then cast to a double
解决方法是在分割之前将分子或分母强制转换为double
:
int a = 7;
int b = 3;
double c = (double)a / b; // = 2.333... because it's cast to a double before
// dividing
//double c = a / (double)b; // this will also work
更具体地说,如果您将代码中的一行更改为此行,则应该有效:
double z = ((double)L.numer/L.denom) - ((double)R.numer/R.denom);