簡體   English   中英

比較分數與結構

[英]Comparing fractions with struct

該函數應該比較存儲在兩個結構中的兩個分數。

  • 如果分數 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);

當您將一個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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM