2012-01-18 17 views
16

Double.parseDouble क्यों बना रहा है 9999999999999999 से 10000000000000000? उदाहरण के लिए:डबल.परसेड डबल 99 99 99 99 99 99 99 99 10000000000000000 क्यों बना रहा है?

Double d =Double.parseDouble("9999999999999999"); 
String b= new DecimalFormat("#.##").format(d); 
System.out.println(b); 

प्रिंट कर रहा है

10000000000000000 

बजाय यह दिखाने के लिए 9999999999999999 या 9999999999999999.00

मदद की किसी भी तरह बहुत सराहना कर रहा है।

+11

(इसके भी रूप में) की जरूरत के साथ सबसे बड़ा प्रदर्शनीय पूर्णांक प्राप्त कर सकते हैं फ्लोटिंग पॉइंट अंकगणित --- 1 9 85 से कंप्यूटर विज्ञान का सबसे बड़ा रहस्य – subsub

उत्तर

12

double देखना केवल सटीकता के 15/16 अंक होते हैं और जब आप इसे एक नंबर यह का प्रतिनिधित्व नहीं कर सकते हैं (जो समय के सबसे अधिक है, देना भी 0.1 है सटीक नहीं) यह निकटतम प्रतिनिधित्व करने योग्य संख्या लेता है।

यदि आप 9999999999999999 बिल्कुल प्रतिनिधित्व करना चाहते हैं, तो आपको BigDecimal का उपयोग करने की आवश्यकता है।

BigDecimal bd = new BigDecimal("9999999999999999"); 
System.out.println(new DecimalFormat("#.##").format(bd)); 

प्रिंट

9999999999999999 

बहुत कम असली दुनिया की समस्याओं इस सटीकता की आवश्यकता है क्योंकि आप कुछ भी इस आकलन नहीं कर सकते सही रूप में वैसे भी। यानि प्रति क्विंटिलियन के 1 भाग की त्रुटि के लिए।


आप

// search all the powers of 2 until (x + 1) - x != 1 
for (long l = 1; l > 0; l <<= 1) { 
    double d0 = l; 
    double d1 = l + 1; 
    if (d1 - d0 != 1) { 
     System.out.println("Cannot represent " + (l + 1) + " was " + d1); 
     break; 
    } 
} 

प्रिंट

Cannot represent 9007199254740993 was 9.007199254740992E15 

सबसे बड़ा प्रदर्शनीय पूर्णांक 9007199254740992 है, क्योंकि यह एक कम बिट

+1

सामान्य आईईईई युगल के बारे में सोचते समय बाइनरी अंकगणित का उपयोग करना कहीं अधिक उपयोगी होता है, यह किसी प्रकार के दशमलव अनुमान का उपयोग करना है। –

+0

9007199254740992 = 20000000000000 (हेक्स) = 10000000000000000000000000000000000000000000000000000000 (बिन) –

+0

@ डोनलफेलोव ट्रू, यही कारण है कि मैं केवल 2 की शक्तियों पर विचार करता हूं। –

15

संख्या 9999999999999999 डबल-परिशुद्धता फ़्लोटिंग-पॉइंट की सटीक सीमा से ऊपर है। दूसरे शब्दों में, 53-बिट मंटिसा 9999999999999999 पकड़ने में सक्षम नहीं है।

तो परिणाम यह है कि यह निकटतम डबल-सटीक मान के लिए गोल है - जो 10000000000000000 है।

9999999999999999 = 0x2386f26fc0ffff // 54 significant bits needed 
10000000000000000 = 0x2386f26fc10000 // 38 significant bits needed 
+0

+1: यह निश्चित रूप से। एक हस्ताक्षरित 99 99 99 99 99 99 99 99 का प्रतिनिधित्व करने के लिए _54_ बिट्स लेते हैं और मानक मूल्य में ठीक से फिट होने वाला सबसे बड़ा मान 9007199254740991 है। –

+0

@DonalFellows यह भी एक संख्या नहीं होगी?यदि 9007199254740991 का प्रतिनिधित्व किया जा सकता है 9007199254740992 का भी प्रतिनिधित्व किया जाना चाहिए। –

+0

@ पीटर: 0x1fffffffffffff एक विषम संख्या है जिसके लिए प्रतिनिधित्व करने के लिए न्यूनतम 53 बिट्स की आवश्यकता होती है। एक नंबर की संख्या के लिए 54 बिट्स (या एक एक्सपोनेंट) की आवश्यकता होती है। मान लें कि वह मान दशमलव में क्या है? :-) –

5

9999999999999999 क्रम में अपूर्णांश के 54 बिट की आवश्यकता है ठीक वैसे ही प्रदर्शित होने के लिए, और double केवल 52. संख्या इसलिए निकटतम संख्या कि एक 52-बिट अपूर्णांश का उपयोग कर प्रदर्शित किया जा सकता करने के लिए गोल है है। यह संख्या 10000000000000000 होती है।

कारण 10000000000000000 के कारण कम बिट्स की आवश्यकता होती है कि इसका बाइनरी प्रतिनिधित्व बहुत सारे शून्यों में समाप्त होता है, और उन शून्यों को (बाइनरी) एक्सपोनेंट बढ़ाकर दर्शाया जा सकता है।

एक ऐसी ही समस्या का विस्तृत विवरण के लिए, Why is (long)9223372036854665200d giving me 9223372036854665216?

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