2011-06-02 19 views
5

मैं एक प्रणाली है कि दशमलव का उपयोग कर गणना के बहुत सारे प्रदर्शन कर रही है, कभी कभी यह एक ही संख्या जोड़ देगा, लेकिन अलग अलग परिणाम देते हैं, +/- 0,000000000000000000000000001अलावा की दशमलव के क्रम को प्रभावित करता है परिणाम

यहाँ एक छोटी उदाहरण है:

decimal a = 2.016879990455473621256359079m; 
decimal b = 0.8401819425625631128956517177m; 
decimal c = 0.4507062854741283043456903406m; 
decimal d = 6.7922317815078349615022988627m; 

decimal result1 = a + b + c + d; 
decimal result2 = a + d + c + b; 

Console.WriteLine((result1 == result2) ? "Same" : "DIFFERENT"); 
Console.WriteLine(result1); 
Console.WriteLine(result2); 

आउटपुट यही कारण है कि:

DIFFERENT 
10.100000000000000000000000000 
10.100000000000000000000000001 

मतभेद इतना छोटा कोई व्यावहारिक प्रभाव है वहाँ है, लेकिन किसी को भी देखा यह ख की तरह कुछ है कर रहे हैं efore? मुझे उम्मीद थी कि एक ही संख्या को जोड़ते समय आपको हमेशा एक ही परिणाम मिलेंगे।

+10

यह StackOverflow पर सबसे आम आवर्ती सवाल है। –

+0

गूगल चल बिन्दु अयथार्थ प्रतिनिधित्व, उस पर विकिपीडिया पढ़ा या तो खोज :) – sehe

+0

यह उल्लेख है कि 'decimal' डेटा प्रकार दौर बंद त्रुटियों के लिए प्रतिरक्षा माना जाता है लायक है। http://msdn.microsoft.com/en-us/library/system.decimal(v=vs.71).aspx –

उत्तर

7

Numerical analysis के पूरे क्षेत्र प्रभाव इस तरह का अध्ययन और उन्हें कैसे से बचने के लिए के लिए समर्पित है।

फ़्लोटिंग पॉइंट नंबरों की सूची एकत्र करते समय सबसे अच्छा परिणाम देने के लिए, पहले सॉर्ट सूची सबसे छोटी से सबसे बड़ी सूची में जोड़ें, और उस क्रम में उन्हें जोड़ें।

+0

चूंकि वह दशमलव का उपयोग कर रहा है (एक फ़्लोटिंग पॉइंट नंबर के विपरीत), क्या यह एक अलग मुद्दा नहीं है? –

+0

@ मार्क, 'दशमलव' _is_ एक फ़्लोटिंग-पॉइंट नंबर है, लेकिन मुद्रा को संभालने के लिए बेहतर टूल प्रदान करने के लिए मंथिसा बनाम एक्सपोनेंट के लिए आवंटित बिट्स की विभिन्न संख्याओं के साथ। 'डबल' में आमतौर पर परिशुद्धता के केवल 14 अंक होंगे, जो कि प्रतिनिधित्व करने के लिए पर्याप्त मंटिसा के किनारे पर सही है। अमेरिका की घाटा सैकड़ों डॉलर के बराबर है। 'दशमलव 'दो अंकों से अधिक का प्रतिनिधित्व कर सकता है, लेकिन छोटे एक्सपोनेंट के कारण बहुत छोटी समग्र सीमा के खर्च पर। – sarnold

+0

+1 विशेष रूप से सॉर्टिंग के बारे में कुछ के लिए +1। :) – sarnold

2

to MSDN अनुसार, एक दशमलव की शुद्धता 28-29 अंक है। आपकी संख्या में से कम से कम एक संख्या 2 9 अंक है, इसलिए आप सीमा से अधिक होने की संभावना है।

2

आपको प्रकार पर संदेह हो सकता है कि double -users के bane पर प्रतिरक्षा हो।

लेकिन because decimal has 28-29 digits of precision और आपका इनपुट डेटा की सटीकता के 2 9 अंकों के योग के लिए पूछ रहा है, तो आप अपने डेटा प्रकार का सटीक रूप से प्रतिनिधित्व करने के बहुत ही किनारे पर सही हैं।

0
क्योंकि कई नंबरों के लिए योग का परिणाम गोलाई की

वे किस क्रम में अभिव्यक्त किया जाता है पर निर्भर करता है भिन्न हो सकते हैं। यह गणित में नहीं होगा, लेकिन आपके उदाहरण में योग की गणना की गई है। result += number; परिणामस्वरूप परिवर्तनीय परिणामस्वरूप परिणाम देता है। उस समय कुछ परिशुद्धता खो गई है। हालांकि, अगर हम इसे एक ही क्रम में करते हैं, तो यह हमेशा एक ही परिणाम में परिणाम देगा।

Console.WriteLine(numbers.Sum()); // Always returns 9.214085249270111332166335344 

इस वजह से कई कार्यक्रम बैंकरों के गोलाकार का उपयोग करते हैं जो निकट परिणाम उत्पन्न करता है। कृपया पता करें कि परिशुद्धता हमेशा खो जाती है। compuiter memor

Rounding

Bankers Rounding

3

पढ़ें The Floating-Point Guide, Floating Point Arithmetic: Issues and Limitations में "सही" चल बिन्दु संख्या स्टोर करने के लिए कोई तरीका नहीं है, और निश्चित रूप What Every Computer Scientist Should Know About Floating-Point Arithmetic की। आह, How to mess with people who’ve learned to expect rounding errors in floating-point math. भी।

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

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