该函数应该比较存储在两个结构中的两个分数。
- 如果分数 L = 分数 R 返回 0
- 如果 L > R 返回 1
- 如果 R > L 返回 -1
这是我现在的代码:
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
如果分子和分母是int
s(或其他整数类型),那么除法是整数除法,你永远不会得到正确的小数部分
将其投射到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 值的检查return L.numer*R.denom - L.denom*R.numer
直接代替
如果您仍然需要返回 -1、0 和 1,那么有几种方法可以缩短/优化它,例如
return (z > 0) - (z < 0);
return (z == 0) ? 0 : (z < 0 ? -1 : 1);
return (z >> 31) | (!!z);
- C/C++ 中有标准的符号函数(signum、sgn)吗?
- C 中整数的快速符号
- 将零、负和正映射到 0、1、2 的无分支代码
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)