2011-11-19 16 views
18

के खिलाफ एक डबल की तुलना में मैं जावा में नया हूं और मैं एक क्यूबिकल समीकरण की जड़ें खोजने के लिए एल्गोरिदम लागू करने की कोशिश कर रहा हूं। समस्या तब उत्पन्न होती है जब मैं भेदभाव की गणना करता हूं और यह जांचने की कोशिश करता हूं कि यह शून्य के सापेक्ष कहां गिरता है।शून्य

आप इसे चलाते हैं और संख्या "1 -5 8 -4" दर्ज करते हैं, उत्पादन इस प्रकार है:

1 -5 8 -4 
p=-0.333333, q=0.074074 
disc1=0.001372, disc2=-0.001372 
discriminant=0.000000000000000
Discriminant is greater than zero. 

मैं जानता हूँ कि समस्या पैदा होती है क्योंकि युगल के साथ गणना सटीक नहीं हैं। आम तौर पर भेदभाव 0 होना चाहिए, लेकिन यह 0.000000000000000जैसा कुछ होता है।

मेरा सवाल है, इससे बचने का सबसे अच्छा तरीका क्या है? क्या मुझे यह जांचना चाहिए कि संख्या शून्य के एक ईपीएसलॉन पड़ोस के बीच होती है या नहीं? या क्या एक बेहतर और अधिक सटीक तरीका है?

आपके उत्तरों के लिए अग्रिम धन्यवाद।

import java.util.Scanner; 

class Cubical { 
    public static void main(String[] args) { 
     // Declare the variables. 
     double a, b, c, d, p, q, gamma, discriminant; 

     Scanner userInput = new Scanner(System.in); 
     a = userInput.nextDouble(); 
     b = userInput.nextDouble(); 
     c = userInput.nextDouble();  
     d = userInput.nextDouble(); 

     // Calculate p and q. 
     p = (3*a*c - b*b)/(3*a*a); 
     q = (2*b*b*b)/(27*a*a*a) - (b*c)/(3*a*a) + d/a; 

     // Calculate the discriminant. 
     discriminant = (q/2)*(q/2) + (p/3)*(p/3)*(p/3); 

     // Just to see the values. 
     System.out.printf("p=%f, q=%f\ndisc1=%f, disc2=%f\ndiscriminant=%.20f\n", p, q, (q/2)*(q/2), (p/3)*(p/3)*(p/3), (q/2)*(q/2) + (p/3)*(p/3)*(p/3)); 

     if (discriminant > 0) { 
      System.out.println("Discriminant is greater than zero."); 
     } 
     if (discriminant == 0) { 
      System.out.println("Discriminant is equal to zero."); 
     } 
     if (discriminant < 0) { 
      System.out.println("Discriminant is less than zero."); 
     } 
    } 
} 

उत्तर

16

सरल एप्सिलॉन जांच

if(Math.abs(value) < ERROR) 

एक अधिक जटिल एक

if(Math.abs(value) < ERROR_FACTOR * Math.max(Math.abs(a), Math.abs(b))) 

मूल्य के लिए आनुपातिक अपने विशिष्ट मामले में आप यह कर सकते है:

if (discriminant > ERROR) { 
    System.out.println("Discriminant is greater than zero."); 
} else if (discriminant < -ERROR) { 
    System.out.println("Discriminant is less than zero."); 
} else { 
    System.out.println("Discriminant is equal to zero."); 
} 
+0

@hattenn: ओपी को, पीटर का दूसरा सुझाव जाने का रास्ता है। –

+0

ईआरआरओआर के लिए कौन सा मूल्य बेहतर है? –

+0

@LunaKong त्रुटि संदर्भ पर निर्भर करता है। यह 1e-12 तक 1e-3 तक हो सकता है या इसे कुछ और होने की आवश्यकता हो सकती है। –

14

मैं जाँच चाहिए संख्या शून्य का एक एप्सिलॉन पड़ोस के बीच गिर जाता है तो क्या होगा?

बिल्कुल

+3

+1 गॉट सीधे सवाल करने के लिए एक शब्द, अयोग्य (कोई 'भारतीय विदेश सेवा या मगर') जवाब का सम्मान करना। –

4

यहाँ समाधान है कि सटीक है जब इनपुट मानों पूर्णांक हैं है हालांकि, यह शायद सबसे व्यावहारिक नहीं है।

यह शायद इनपुट मूल्यों पर भी ठीक काम करेगा जिसमें सीमित बाइनरी प्रतिनिधित्व (उदाहरण के लिए 0.125 करता है, लेकिन 0.1 नहीं)।

चाल: मध्यवर्ती परिणामों से सभी डिवीजनों को हटाएं और केवल अंत में एक बार विभाजित करें। यह सभी (आंशिक) संख्याओं और denominators का ट्रैक रखकर किया जाता है। यदि भेदभाव 0 होना चाहिए तो यह संख्या 0 होगा। जब तक इंटरमीडिएट परिवर्धन पर मान एक दूसरे से (2 आमतौर पर मामला) की मात्रा के भीतर होते हैं, तब तक कोई राउंड-ऑफ़ त्रुटि नहीं होती है।

// Calculate p and q. 
double pn = 3 * a * c - b * b; 
double pd = 3 * a * a; 

double qn1 = 2 * b * b * b; 
double qd1 = 27 * a * a * a; 
double qn2 = b * c; 
double qn3 = qn1 * pd - qn2 * qd1; 
double qd3 = qd1 * pd; 
double qn = qn3 * a + d * qd3; 
double qd = qd3 * a; 

// Calculate the discriminant. 
double dn1 = qn * qn; 
double dd1 = 4 * qd * qd; 
double dn2 = pn * pn * pn; 
double dd2 = 27 * pd * pd * pd; 

double dn = dn1 * dd2 + dn2 * dd1; 
double dd = dd1 * dd2; 
discriminant = dn/dd; 

(केवल प्रदान की इनपुट मानों पर जाँच की है, तो मुझे बताओ अगर कुछ गलत है)

+0

मैंने मध्यवर्ती परिणामों से कुछ डिवीजनों को हटा दिया है और यह अब बहुत बेहतर काम करता है। चेतावनी देने के लिए आपका धन्यवाद। – hattenn

संबंधित मुद्दे