2014-04-20 5 views
2

이 함수는 구조체에 저장된 두 분수를 비교합니다. 분수 L = 분수 R이 0을 반환하면 L> R이면 R> L이 -1을 반환하면 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; 
} 

그러나 나는 공의는 다음 비교에 나타납니다

(1,3) ? (2,3) 
(5,6) ? (3,4) 
(2,4) ? (1,4) 

곳 (1,3) 분수 L과 (2, 3) 분수 R입니다. 미리 감사드립니다!

+2

그리고 z가 0 인 테스트는 나쁘다. http://stackoverflow.com/questions/19837576/comparing-floating-point-number-to-zero – Throwback1986

답변

2

분자와 분모가 int이면 나눗셈은 정수 나누기입니다. corr을 얻지 못할 것입니다. 분수 부분

두 배로 캐스팅하면 대부분의 문제를 해결할 수 있지만 부동 소수점 반올림으로 인한 느린 구분과 오류가 발생할 수 있습니다.

대신 곱하기를 사용해야합니다. 훨씬 빠르며 일부 아키텍처에서는 매우 느린 부동 소수점 나누기가 필요하지 않습니다. 부동 소수점 비교에 대해 걱정할 필요가 없습니다이 방법은 너무

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; 
} 

는 당연히 모든 분모가 긍정적 있는지 확인해야합니다. 그렇지 않으면 그것을 정규화해야합니다.

+1

표준화 제안 : 'int z = ...; if (R.denom <0) z = -z; if (L.denom <0) z = -z;'주의 : int를 사용하는 것의 단점은 정수 오버 플로우입니다. 더 넓은'int' 크기로가는 것이 도움이되지만 중대한 해결책이 아닙니다. 그러나 당신의 대답은 올바른 접근법입니다. – chux

+0

@chux 대부분의 아키텍처는 확장 된 곱셈을 사용하므로 더 넓은 int 유형을 사용하는 것이 그리 큰 문제는 아니며 int에서 double로 숫자를 변환 한 다음 나누는 것보다 더 빠릅니다. –

+0

대부분의 아키텍처가 더 넓은 정수를 동의합니다. 'intmax_t'를 사용하는 것이 일반적으로 안전한 후보가됩니다. 그렇지 않다면, 당신이 고용 한 똑같은 디비디리스 방식으로 '더블'을 사용할 수 있습니다. – chux

0

int을 다른 int으로 나눌 때 결과가 0이되도록 int이어야하므로 결과를 0으로 반올림합니다. 우선이 시점에서 그것은 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);