2012-11-20 99 views
7

क्या यह संभव है कि यह भी संभव है कि जावा में दो double मानों (जोड़/घटाव) के साथ व्यवहार करते समय अधिकतम सटीक हानि क्या होगी? शायद सबसे खराब स्थिति परिदृश्य तब होता है जब दो संख्याओं का बिल्कुल प्रतिनिधित्व नहीं किया जा सकता है, और उसके बाद एक ऑपरेशन किया जाता है, जिसके परिणामस्वरूप एक मान होता है जिसे बिल्कुल प्रदर्शित नहीं किया जा सकता है।जावा - एक डबल अतिरिक्त/घटाव में सटीकता का अधिकतम नुकसान

+0

यदि सटीक हानि एक मुद्दा है, तो मैं डबल की बजाय बिगडेसिमल का उपयोग करने की अनुशंसा करता हूं। –

+0

हाँ, इस सवाल का पूरा बिंदु यह देखना है कि नुकसान कितना बड़ा है। डबल 8 बाइट लेता है, जबकि 40 के आसपास बिगडिसीमल, और मुझे बहुत सारे डेटा पॉइंट्स स्टोर करने की आवश्यकता है – Bober02

+0

जब आप बहुत सारे फ़्लोटिंग-पॉइंट ऑपरेशंस करते हैं, तो ऑब्जेक्ट्स के बजाय प्राइमेटिव्स का उपयोग करने का प्रदर्शन लाभ महत्वपूर्ण हो सकता है। – Cephalopod

उत्तर

5

Math.ulp(double) पर एक नज़र डालें। double का अगला उच्चतम मूल्य वाला डेल्टा है। उदाहरण के लिए, यदि आप संख्याओं में जोड़ते हैं और एक दूसरे के उलझन से छोटा होता है, तो आप जानते हैं कि अतिरिक्त प्रभाव नहीं होगा। यदि आप दो युगल गुणा करते हैं, तो आप परिणाम की अधिकतम त्रुटि प्राप्त करने के लिए अपने ulps गुणा कर सकते हैं।

+0

यह वही है जो मैं चाहता था – Bober02

7

सबसे खराब मामला यह है कि सभी परिशुद्धता खो जा सकती है। यह उदाहरण के लिए हो सकता है यदि परिणाम सबसे बड़ा प्रतिनिधित्व करने योग्य सीमित संख्या से बड़ा है। फिर इसे POSITIVE_INFINITY (या NEGATIVE_INFINITY) के रूप में संग्रहीत किया जाएगा।

आपके अपडेट के संबंध में, यह अतिरिक्त के साथ भी हो सकता है।

double a = Double.MAX_VALUE; 
System.out.println(a); 
double b = a + a; 
System.out.println(b); 

परिणाम:

1.7976931348623157E308 
Infinity 

यह ऑनलाइन देखें: ideone

सामान्य में प्रतिनिधित्व त्रुटि के आकार अपने नंबरों के आकार के सापेक्ष है।

+0

उपरोक्त संपादन देखें - मेरा मतलब अधिकतर अतिरिक्त है ... – Bober02

0

उदाहरण के लिए आउटपुट नीचे कोड अपने आदानों की वास्तविक परिशुद्धता पर एक नज़र हो सकता है:

input: 0.01000000000000000020816681711721685132943093776702880859375 
range: [0.0099999999999999984734433411404097569175064563751220703125 - 0.010000000000000001942890293094023945741355419158935546875] 
range size: 3.4694469519536141888238489627838134765625E-18 
input: 10000000000000000 
range: [9999999999999998 - 10000000000000002] 
range size: 4 
public static void main(String[] args) { 
    printRange(0.01); 
    printRange(10000000000000000d); 
} 

private static void printRange(double d) { 
    long dBits = Double.doubleToLongBits(d); 
    double dNext = Double.longBitsToDouble(dBits + 1); 
    double dPrevious = Double.longBitsToDouble(dBits + -1); 
    System.out.println("input: " + new BigDecimal(d)); 
    System.out.println("range: [" + new BigDecimal(dPrevious) + " - " + new BigDecimal(dNext) + "]"); 
    System.out.println("range size: " + new BigDecimal(dNext - dPrevious)); 
} 

तुम अब भी तो के परिणाम पर नुकसान का अनुमान लगाने की आवश्यकता होगी आपकी ऑपरेशन। और यह कोने के मामलों (इन्फिनिटी, नाएन इत्यादि के आसपास) के साथ काम नहीं करता है।