क्या यह संभव है कि यह भी संभव है कि जावा में दो double
मानों (जोड़/घटाव) के साथ व्यवहार करते समय अधिकतम सटीक हानि क्या होगी? शायद सबसे खराब स्थिति परिदृश्य तब होता है जब दो संख्याओं का बिल्कुल प्रतिनिधित्व नहीं किया जा सकता है, और उसके बाद एक ऑपरेशन किया जाता है, जिसके परिणामस्वरूप एक मान होता है जिसे बिल्कुल प्रदर्शित नहीं किया जा सकता है।जावा - एक डबल अतिरिक्त/घटाव में सटीकता का अधिकतम नुकसान
उत्तर
Math.ulp(double)
पर एक नज़र डालें। double
का अगला उच्चतम मूल्य वाला डेल्टा है। उदाहरण के लिए, यदि आप संख्याओं में जोड़ते हैं और एक दूसरे के उलझन से छोटा होता है, तो आप जानते हैं कि अतिरिक्त प्रभाव नहीं होगा। यदि आप दो युगल गुणा करते हैं, तो आप परिणाम की अधिकतम त्रुटि प्राप्त करने के लिए अपने ulps गुणा कर सकते हैं।
यह वही है जो मैं चाहता था – Bober02
सबसे खराब मामला यह है कि सभी परिशुद्धता खो जा सकती है। यह उदाहरण के लिए हो सकता है यदि परिणाम सबसे बड़ा प्रतिनिधित्व करने योग्य सीमित संख्या से बड़ा है। फिर इसे 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
सामान्य में प्रतिनिधित्व त्रुटि के आकार अपने नंबरों के आकार के सापेक्ष है।
उपरोक्त संपादन देखें - मेरा मतलब अधिकतर अतिरिक्त है ... – Bober02
उदाहरण के लिए आउटपुट नीचे कोड अपने आदानों की वास्तविक परिशुद्धता पर एक नज़र हो सकता है:
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));
}
तुम अब भी तो के परिणाम पर नुकसान का अनुमान लगाने की आवश्यकता होगी आपकी ऑपरेशन। और यह कोने के मामलों (इन्फिनिटी, नाएन इत्यादि के आसपास) के साथ काम नहीं करता है।
यदि सटीक हानि एक मुद्दा है, तो मैं डबल की बजाय बिगडेसिमल का उपयोग करने की अनुशंसा करता हूं। –
हाँ, इस सवाल का पूरा बिंदु यह देखना है कि नुकसान कितना बड़ा है। डबल 8 बाइट लेता है, जबकि 40 के आसपास बिगडिसीमल, और मुझे बहुत सारे डेटा पॉइंट्स स्टोर करने की आवश्यकता है – Bober02
जब आप बहुत सारे फ़्लोटिंग-पॉइंट ऑपरेशंस करते हैं, तो ऑब्जेक्ट्स के बजाय प्राइमेटिव्स का उपयोग करने का प्रदर्शन लाभ महत्वपूर्ण हो सकता है। – Cephalopod