2010-01-04 9 views
7

मैं अपने कोल्डफ्यूजन कोड में इन मानों पर हुआ लेकिन Google कैलकुलेटर में एक ही "बग" है जहां अंतर शून्य है।यह घटाव शून्य के बराबर क्यों नहीं है?

416,582.2850-411,476.8100 - 5105,475 = -2.36468622461E-011

http://www.google.com/search?hl=en&rlz=1C1GGLS_enUS340US340&q=416582.2850+-+411476.8100+-+5105.475&aq=f&oq=&aqi=

लंबे/नाव करने के लिए इन JavaCast'ing/डबल यह मदद के नहीं है अन्य गैर शून्य मतभेद का परिणाम है।

+16

SO पर खाता बनाते समय एक फ़्लोटिंग पॉइंट प्रश्नोत्तरी होना चाहिए। मुझे लगता है कि यह साइट पर सबसे आम तौर पर पूछे जाने वाले प्रश्न है। – recursive

+3

@recursive: http://meta.stackexchange.com/questions/26621/whats-the-most-repeated-question-on-stackoverflow/26633#26633 –

+1

जब मैंने प्रोग्राम करना सीखा, फ्लोटिंग पॉइंट नंबरों में सटीकता की कमी पहली बार फ्लोटिंग पॉइंट पर चर्चा की गई थी, और उसके बाद कई बार उल्लेख किया गया था। क्या वे ऐसा नहीं करते हैं? –

उत्तर

16

ऐसा इसलिए है क्योंकि बेस 10 में "लुक" राउंड दशमलव संख्याएं बेस 2 में बिल्कुल प्रतिनिधित्व नहीं करती हैं (जो कंप्यूटर फ़्लोटिंग पॉइंट नंबरों का प्रतिनिधित्व करने के लिए उपयोग करते हैं)। कृपया इस समस्या और कामकाज की विस्तृत व्याख्या के लिए आलेख What Every Computer Scientist Should Know About Floating-Point Arithmetic देखें।

+1

5105.475 वह संख्या थी जो वास्तव में एक डबल में प्रदर्शित नहीं थी। प्रेसिजनएवलुएट कोल्डफ्यूजन फ़ंक्शन की आवश्यकता है। –

+0

वास्तव में, उन संख्याओं में से कोई भी डबल सटीक मानों के रूप में बिल्कुल प्रतिनिधित्व योग्य नहीं है। –

+0

+1 उत्कृष्ट संदर्भ, जीएल स्टील –

7

फ़्लोटिंग-पॉइंट त्रुटियों (वास्तविक संख्याओं की असीमित संख्या और केवल 32- या 64-बिट संख्याओं की एक सीमित संख्या के साथ उनका प्रतिनिधित्व करने के लिए) हैं।

यदि आप छोटी त्रुटियों को संभाल नहीं सकते हैं, तो आपको इसके बजाय BigDecimal का उपयोग करना चाहिए।

+1

संदर्भ: http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems –

+0

लेकिन 416582.2850 - 411476.8100 का प्रतिनिधित्व * बिल्कुल * 5105.475 के रूप में किया जा सकता है। ये संख्या केवल 4 दशमलव के साथ हैं, दोहराने नहीं। क्या 4 दशमलव बहुत सटीक हैं? –

+2

यह आधार -10 प्रतिनिधित्व नहीं है जिसे सीमित होना है, यह आधार -2 प्रतिनिधित्व है। Http://en.wikipedia.org/wiki/Binary_numeral_system#Fractions_in_binary देखें कि किस अंश का वास्तव में बाइनरी में प्रदर्शित किया जा सकता है (यह केवल वे हैं जिनके पास 2 denominator का मुख्य कारक है)। –

1

समस्या फ्लोटिंग पॉइंट प्रकारों का अचूक प्रतिनिधित्व है। चूंकि इन्हें फ्लोट्स के रूप में बिल्कुल सही नहीं माना जा सकता है, इसलिए आपको कुछ सटीक हानि मिलती है जिसके परिणामस्वरूप संचालन में छोटी त्रुटियां होती हैं। आम तौर पर फ्लोट्स के साथ आप तुलना करना चाहते हैं कि परिणाम कुछ छोटे एपिसल (त्रुटि कारक) के भीतर किसी अन्य मान के बराबर है या नहीं।

2

चूंकि कंप्यूटर बाइनरी में संख्याओं को स्टोर करता है, फ्लोट संख्या कमजोर होती है। 1E-11 इन दशमलव संख्याओं को निकटतम प्रतिनिधित्व करने योग्य बाइनरी संख्या में गोल करने के कारण एक छोटा सा अंतर है।

2

यह "बग" एक बग नहीं है। यह कैसे अस्थायी बिंदु अंकगणित काम करता है। देखें: http://docs.sun.com/source/806-3568/ncg_goldberg.html

आप जावा में मनमाने ढंग से सटीक चाहते हैं, BigDecimal का उपयोग करें:

BigDecimal a = new BigDecimal("416582.2850"); 
    BigDecimal b = new BigDecimal("411476.8100"); 
    BigDecimal c = new BigDecimal("5105.475"); 
    System.out.println(a.subtract(b).subtract(c)); // 0.0 
1

ये बिंदु मुद्दों फ्लोटिंग और BigDecimal का उपयोग कर इसे ठीक कर देंगे कर रहे हैं।

घटाव के क्रम को बदलना भी Google में शून्य उत्पन्न करता है।

416582.2850 - 5105.475 - 411476.8100 = 0 
5

ColdFusion में उपयोग PrecisionEvaluate() (यह जावा में BigDecimal इस्तेमाल करेंगे)

zero = PrecisionEvaluate(416582.2850 - 411476.8100 - 5105.475); 

Evaulate() के विपरीत, कोई "" की जरूरत है।

+1

+1 – Kip

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