[英]Comparing fractions with struct
該函數應該比較存儲在兩個結構中的兩個分數。
這是我現在擁有的代碼:
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);
當您將一個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);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.