2012-03-28 18 views
10

मेरे सहकर्मी इस प्रयोग किया:डबल घटाव सटीक मुद्दा

0.005 

लेकिन अप्रत्याशित रूप से उत्पादन किया गया था::

0.0050000000000001155 

public class DoubleDemo { 

     public static void main(String[] args) { 
      double a = 1.435; 
      double b = 1.43; 
      double c = a - b; 
      System.out.println(c); 
     } 
} 

यह पहली ग्रेड आपरेशन के लिए मैं इस उत्पादन की उम्मीद

इस तरह के एक सरल ऑपरेशन में डबल क्यों विफल रहता है? और यदि इस काम के लिए दैटैट टाइप नहीं है, तो मुझे क्या उपयोग करना चाहिए?

+0

आपके प्रयोग को साझा करने के लिए धन्यवाद। +1 – kasavbere

+0

मुझे यकीन है कि यह डुप्लिकेट –

+0

संभावित डुप्लिकेट [जावा में डबल्स के साथ सटीक बनाए रखें] (http://stackoverflow.com/questions/322749/retain-precision-with-doubles-in-java) –

उत्तर

17

double आंतरिक द्विआधारी में एक अंश के रूप में जमा है - या मूल्य 1.435 - - 1/4 + 1/8 + 1/16 + ...

मूल्य 0.005 की तरह एक सटीक अंश बाइनरी में है, इसलिए double सटीक संग्रहीत नहीं कर सकता के रूप में जमा नहीं किया जा सकता मूल्य 0.005, और घटाया गया मान बिल्कुल सटीक नहीं है।

यदि आप सटीक दशमलव अंकगणित के बारे में परवाह करते हैं, तो BigDecimal का उपयोग करें।

आपको this article उपयोगी पढ़ने भी मिल सकता है।

+0

+ 1 BigDecimal का प्रयोग करें या अपने परिणाम के दौर। –

2

डबल और फ्लोट बिल्कुल वास्तविक संख्या नहीं हैं।

किसी भी श्रेणी में वास्तविक संख्याओं की असीमित संख्या है, लेकिन केवल प्रतिनिधित्व करने के लिए बिट्स की सीमित संख्या! इस कारण से, गोल और त्रुटियों के लिए गोल करने की त्रुटियों की उम्मीद है।

आपको जो संख्या मिलती है वह निकटतम संख्या संभव है जिसे फ़्लोटिंग पॉइंट प्रस्तुति में डबल द्वारा दर्शाया जा सकता है।

अधिक जानकारी के लिए, आप this article पढ़ सकते हैं [चेतावनी: उच्च स्तर हो सकता है]।

आप BigDecimal का उपयोग दशमलव संख्या प्राप्त करने के लिए करना चाहते हैं [लेकिन जब आप 1/3 प्राप्त करने का प्रयास करते हैं तो आपको दोबारा त्रुटियों का सामना करना पड़ेगा]।

1

double और float अंकगणित "हुड के नीचे" होने वाली राउंडिंग के कारण बिल्कुल सही नहीं होगा।

अनिवार्य रूप से युगल और फ्लोट्स में असीमित मात्रा में दशमलव हो सकते हैं लेकिन स्मृति में उन्हें कुछ वास्तविक संख्याओं द्वारा दर्शाया जाना चाहिए। तो जब आप यह दशमलव अंकगणित करते हैं तो एक गोल प्रक्रिया होती है और यदि आप सभी दशमलव को खाते में लेते हैं तो अक्सर बहुत कम राशि से बंद होता है।

जैसा कि पहले बताया गया है, यदि आपको पूरी तरह सटीक मानों की आवश्यकता है तो BigDecimal का उपयोग करें जो इसके मूल्यों को अलग-अलग स्टोर करता है। Here's the API

+0

यह कहना सही नहीं है कि वे "कभी" बिल्कुल सही नहीं होंगे। यह कहना सही होगा कि वे कभी भी सही नहीं होंगे जब भिन्नता के अलावा किसी अन्य चीज का प्रतिनिधित्व करते हैं जिसका denominator दो की शक्ति नहीं है। – supercat

-1
//just try to make a quick example to make b to have the same precision as a has, by using BigDecimal 

private double getDesiredPrecision(Double a, Double b){ 
    String[] splitter = a.toString().split("\\."); 
    splitter[0].length(); // Before Decimal Count 
    int numDecimals = splitter[1].length(); //After Decimal Count 

    BigDecimal bBigDecimal = new BigDecimal(b); 
    bBigDecimal = bBigDecimal.setScale(numDecimals,BigDecimal.ROUND_HALF_EVEN); 

    return bBigDecimal.doubleValue(); 
} 
+0

यह सवाल का जवाब नहीं देता है। –

+0

अच्छी तरह से, आप सही हैं। बस BigDecimal पर कुछ छोटा उदाहरण बनाने की कोशिश करें। पहले से ही सवाल का जवाब देने वाले लोग हैं। दोहराव की जरूरत नहीं है। – madmaximshen

+0

SO पर, उत्तर एक पूर्ण, स्वयं निहित उत्तर प्रदान करने के लिए हैं। अगर आपको लगता है कि किसी अन्य उत्तर में कुछ गुम है, तो पर्याप्त प्रतिष्ठा मिलने के बाद एक टिप्पणी छोड़ दें। यदि आपको लगता है कि आप एक बेहतर * पूर्ण * उत्तर लिख सकते हैं, तो ऐसा करें। इस तरह "अर्ध-जवाब" पोस्ट न करें। –

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