2013-10-15 5 views
0

(0, 1) 간격으로 2 차 방정식의 최하위 루트를 반환하는 Java 메소드를 생성하려고합니다. 해당 간격에 솔루션이 없으면 1을 반환하십시오. 이 알고리즘을 효율적으로 만드는 데 도움이 필요합니다.특정 간격으로 가장 낮은 이차 루트 찾기

이 내 현재의 방법입니다 :

public static float getLowestRoot(float A, float B, float C) { 
    float D = B*B - 4*A*C; 
    if(D < 0) return 1; 

    float sD = (float) Math.sqrt(D); 

    float x1 = (-B + sD)/(2*A); 
    float x2 = (-B - sD)/(2*A); 

    if(x2 < x1) { 
     float tmp = x2; 
     x2 = x1; 
     x1 = tmp; 
    } 

    if(x1 > 0 && x1 < 1) return x1; 
    if(x2 > 0 && x2 < 1) return x2; 

    return 1; 
} 

이 방법은 일을하지만 지금은 비 대한 느낌 때문에 알고리즘을 압축 할 수있는 방법이 있는지 궁금 해서요.

+0

어떤 솔루션이 1 인 경우 :

그래서, 최종 대답은 같을까요? – arynaq

+0

'float'을'double'으로 바꾸는 것이 좋습니다. 더 정확한 결과를 얻을 수 있습니다. –

+0

난 근본적으로 당신의 코드에 문제가 없다고 생각한다. (물론 올바른 해결책이기 때문에 1.0을 "사용하지 않는다"는 것을 제외하고). – NPE

답변

0

1) "적은 코드 행"은 "성능 향상"과 같지 않습니다.

2)Math.abs(sD) < Epsilon - 그렇다면 루트를 모두 계산할 필요가 없습니다. 저는 을 추측합니다.이 경우 속도를 향상시킬 수 있다고은 추측합니다.

x1 <= x2 <===> -B+sD/(2A) <= -B-sD/(2A) <==(adding sD/(2A) to both sides)==> 
     <===> -B+2sD/(2A) <= -B/(2A) <==(adding B/(2A) to both sides)==> 
     <===> 2sD/(2A) <= 0 
     <===>   A <= 0 (because sD >= 0) 

그래서 당신이 뿌리 교환 피할 수 있습니다 :

3) 난 당신이 루트가 작 검사 향상시킬 수 있다고 생각 다시

int signA = Math.signum(A); 
float x1 = (-B + -signA * sD)/(2*A); 
float x2 = (-B + signA * sD)/(2*A); 

// always x1 <= x2 

을, 나는 을 추측하고있어 그 성능이 향상되었지만 측정하지는 못했습니다.

public static float getLowestRoot(float A, float B, float C) { 
    float D = B*B - 4*A*C; 

    if (D < 0) return 1; 

    if (Math.abs(D) < 0.0001) // not sure how many 0s for float 
    { 
     float x = -B/(2*A); 

     if (x > 0 && x < 1) return x; 

     return 1; 
    } 

    float sD = (float) Math.sqrt(D); 

    int signA = Math.signum(A); 
    float x1 = (-B + -signA * sD)/(2*A); 
    float x2 = (-B + signA * sD)/(2*A); 

    if (x1 > 0 && x1 < 1) return x1; 
    if (x2 > 0 && x2 < 1) return x2; 

    return 1; 
} 
+0

@Wilco 일부 성능 아이디어를 보여주기 위해 답변을 변경했습니다. – BartoszKP

+0

답변 해 주셔서 감사합니다! – Wilco

관련 문제