.NET बैंकर की गोलाई को डिफ़ॉल्ट के रूप में क्यों उपयोग करता है?


271

प्रलेखन के अनुसार, decimal.Roundविधि एक गोल-से-समरूप एल्गोरिथ्म का उपयोग करती है जो अधिकांश अनुप्रयोगों के लिए सामान्य नहीं है। इसलिए मैं हमेशा अधिक प्राकृतिक राउंड-अप-अप एल्गोरिथ्म करने के लिए एक कस्टम फ़ंक्शन लिखना समाप्त करता हूं:

public static decimal RoundHalfUp(this decimal d, int decimals)
{
    if (decimals < 0)
    {
        throw new ArgumentException("The decimals must be non-negative", 
            "decimals");
    }

    decimal multiplier = (decimal)Math.Pow(10, decimals);
    decimal number = d * multiplier;

    if (decimal.Truncate(number) < number)
    {
        number += 0.5m;
    }
    return decimal.Round(number) / multiplier;
}

किसी को भी इस रूपरेखा डिजाइन निर्णय के पीछे का कारण पता है?

क्या ढांचे में राउंड-हाफ-अप एल्गोरिथम का कोई अंतर्निहित कार्यान्वयन है? या शायद कुछ अप्रबंधित विंडोज एपीआई?

यह शुरुआती लोगों के लिए भ्रामक हो सकता है जो केवल decimal.Round(2.5m, 0)3 परिणाम के रूप में अपेक्षा करते हैं लेकिन इसके बजाय 2 प्राप्त करते हैं।


105
चक्कर लगाना "अधिक प्राकृतिक" नहीं है। प्रकृति का इससे कोई लेना-देना नहीं है। जब आपने "गोलाई" की अवधारणा सीखी तो बस यह कि आपने ग्रेडस्कूल में क्या सीखा। ग्रेडस्कूल सबक हमेशा एक पूरी तस्वीर पेंट नहीं करते हैं।
राब कैनेडी

45
@ रोब और इसलिए यह अधिक प्राकृतिक है , भले ही यह सही
Pacerier

10
मुझे समझ में नहीं आता, @Pacerier। मैंने समझाया कि यह प्राकृतिक क्यों नहीं है , और आप कहते हैं कि वास्तव में यह प्राकृतिक क्यों है । मेरा तर्क मेरे निष्कर्ष के खिलाफ कैसे काम करता है , जो आपके विपरीत है? आप जिन चीजों के आदी हो चुके हैं , वे स्वाभाविक रूप से महसूस कर सकते हैं , और कभी-कभी हम लाक्षणिक रूप से कहते हैं कि कुछ "दूसरी प्रकृति" है, लेकिन यह उन्हें प्राकृतिक नहीं बनाता है।
रॉब केनेडी

16
@ रब मैं कह रहा हूं कि यह स्वाभाविक है, क्योंकि यह प्राकृतिक लगता है। आप जानते हैं कि एक ही चर नाम प्राकृतिक अधिकार के साथ 36 अलग-अलग वस्तुएं हैं ?
पचेरियर

9
प्रकृति का रक्षात्मक रूप से एनालॉग इसलिए इसका उपयोग करने के लिए गलत शब्द है; लेकिन यह पांडित्य है। हो सकता है कि 'सामान्य' का उपयोग करने के लिए एक बेहतर शब्द होगा .. "सामान्य राउंडिंग क्या है जो लोग करते हैं"> 0.5 1.0 तक जाता है
Whytheq

जवाबों:


196

शायद इसलिए कि यह एक बेहतर एल्गोरिदम है। प्रदर्शन किए गए कई राउंडिंग के दौरान, आप औसतन .5 के अंत तक समान रूप से ऊपर और नीचे राउंडिंग करेंगे। यह वास्तविक परिणामों का बेहतर अनुमान देता है यदि आप उदाहरण के लिए, गोल संख्याओं का एक गुच्छा जोड़ रहे हैं। मैं कहूंगा कि भले ही यह कुछ की उम्मीद न हो, लेकिन यह शायद अधिक सही बात है।


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

7
बेहतर एल्गोरिथ्म के लिए +1 , हालांकि ओस्तेमर का वास्तविक उत्तर है ( stackoverflow.com/questions/311696/… )
इयान बॉयड

2
@, मैं उस उत्तर को +1 भी देता हूं। वैसे भी हम "स्वीकार किए गए उत्तर को स्थानांतरित कर सकते हैं" शायद ओपी ऐसा कर सकते हैं। इस पद्धति का उपयोग "क्यों" करने के लिए वास्तविक उत्तर पृष्ठ से आधा नीचे है। हालांकि मुझे इस उत्तर से सप्ताह में एक बार मिलने वाले रेप बूस्ट काफी पसंद हैं।
कबि

@ तिब्बती - मेरे जवाब को आगे बढ़ाने के लिए धन्यवाद। मुझे लगता है कि यह ओपी के लिए स्वीकृत उत्तर को बदलने के लिए निर्भर है क्योंकि वह फिट दिखता है?
ओस्टेमार

-1 के लिए यह एक बेहतर एल्गोरिथ्म है। - बैंकर के चक्कर का उपयोग करके संख्या के एक यादृच्छिक नमूने को देखते हुए आप विषम पदों की तुलना में अधिक पदों पर अधिक संख्या में समाप्त हो जाएंगे। - यह आपके द्वारा उन संख्याओं को औसत करने के बाद ही होता है जो आपको मूल वितरण के समान फिर से मिलते हैं। - हालांकि अगर आप उदाहरण के लिए इस डेटा को स्कैटर प्लॉट में प्लॉट करते हैं तो कोई कृत्रिम ग्रुपिंग देख सकता है।
पौल २३

437

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

लेकिन सवाल यह था कि क्यों .NET बैंकर की वास्तविक गोलाई को डिफ़ॉल्ट के रूप में उपयोग करता है - और उत्तर यह है कि Microsoft ने IEEE 754 मानक का पालन किया है । इसका उल्लेख MSDN फॉर मैथ.ाउंड फॉर रिमार्क्स के तहत भी किया गया है ।

यह भी ध्यान दें कि .NET ज्ञानवर्धन प्रदान करके IEEE द्वारा निर्दिष्ट वैकल्पिक विधि का समर्थन करता है MidpointRounding। वे निश्चित रूप से संबंधों को सुलझाने के लिए अधिक विकल्प प्रदान कर सकते हैं, लेकिन वे IEEE मानक को पूरा करने के लिए चुनते हैं।


17
तो, IEEE 754 बैंकरों के चक्कर क्यों लगाता है? यह (अभी भी अच्छा) उत्तर सिर्फ बाल्टी पास करता है।
हेंक होल्टरमैन

4
@HenkHolterman संभवतः अन्य उत्तरों में उल्लेखित होने के कारण (और जैसा कि मैंने संक्षेप में बताया है); यह नकारात्मक या सकारात्मक पूर्वाग्रह से ग्रस्त (बहुत अधिक) नहीं होता है और जैसा कि अधिकांश वितरण और समस्या डोमेन के लिए अधिक गूंजने योग्य डिफ़ॉल्ट के लिए होता है।
ओस्टमर


मुझे लगता है कि यह दिलचस्प है क्योंकि IEEE 754 फ्लोटिंग पॉइंट संख्याओं के लिए मानक है, जिसमें दशमलव नहीं है। हो सकता है कि यह IEEE 754 का अनुसरण करता हो, ताकि उसी एल्गोरिथ्म का उपयोग दशमलव के रूप में डबल राउंडिंग के लिए किया जाए।
ब्रैंडन बार्कले

1
@BrandonBarkley एक दशमलव या दशमलव है एक चल बिन्दु संख्या, और आईईईई 754 शामिल नहीं है दशमलव चल बिन्दु संख्या।
पाब्लो एच

88

हालांकि मैं इस सवाल का जवाब नहीं दे सकता कि "माइक्रोसॉफ्ट के डिजाइनरों ने इसे डिफ़ॉल्ट के रूप में क्यों चुना?", मैं सिर्फ यह बताना चाहता हूं कि एक अतिरिक्त फ़ंक्शन अनावश्यक है।

Math.Roundआपको निर्दिष्ट करने की अनुमति देता है MidpointRounding:

  • ToEven - जब एक संख्या दो अन्य लोगों के बीच आधी होती है, तो इसे निकटतम सम संख्या की ओर गोल किया जाता है।
  • AwayFromZero - जब एक संख्या दो अन्य के बीच आधी होती है, तो इसे निकटतम संख्या की ओर गोल किया जाता है जो शून्य से दूर होती है।

8
और जैसा कि मैंने संबंधित थ्रेड्स में उल्लेख किया है, सुनिश्चित करें कि आप अपनी गोलाई में सुसंगत हैं - यदि आप कभी डेटाबेस में और कभी-कभी .net में राउंडिंग करते हैं, तो आपके पास अजीब होंगे, एक प्रतिशत त्रुटियां जो आपको सप्ताह लगेंगी। अंदाजा लगाओ।
क्रिस

59
एक ग्राहक ने एक बार $ 40,000 से अधिक का भुगतान किया, जो कि दो बिलों के बीच $ 0.11 गोलाई की गड़बड़ी को ट्रैक करने के लिए था, जो दोनों केवल 1 बिलियन डॉलर का शर्मीला था; $ 0.11 एक मेनफ्रेम और एसक्यूएल सर्वर के बीच 8 वीं अंक के गोल त्रुटि में अंतर के कारण था। एक पूर्णतावादी के बारे में बात करो!
ईजे ब्रेनन

12
@EJB - अगर मैं एक बिलियन डॉलर के साथ काम कर रहा होता तो मैं शायद एक पूर्णतावादी होता; ;-)
royse41

12
@ ईजे ब्रेनन: यह पता लगाने के लिए आपको $ 40k लग गए? मैं हर समय इस तरह की समस्याओं को देखता हूं, गोलाई # 1 का कारण है, डबल / फ्लोट सामान्यीकरण का कारण # 2 है, प्रोग्रामर त्रुटि # 3 - # 3 को पूर्व निर्धारित परीक्षण मामलों में न होने पर तुरंत # 1 पर सेट किया जा सकता है। btw क्या आप मुझे अपने अरबपति ग्राहक के संपर्क में रख सकते हैं, मुझे लगता है कि मुझे उनके सिस्टम में कुछ और $ 40k कीड़े भी मिल सकते हैं! : डी

3
@ सीन: यदि आपने ऑफिस स्पेस देखा है। सच में, जब भी आप पैसे में रहस्यमय, छोटे अशुद्धि देखते हैं, तो वास्तव में वे कैसे हो रहे हैं के रहस्य को सुलझाते हुए लगभग हमेशा एक अच्छा विचार है। यह संभव है कि आप बग्स को ठीक नहीं करने का निर्णय लेंगे, लेकिन अंतर्निहित कारण जानने के बाद भी मूल्य है। मैं शर्त लगाता हूं कि बहुत से लोग जो पैसे के साथ काम करते हैं वे छोटे अशुद्धि को भी नोटिस करते हैं।
ब्रायन

22

दशमलव का उपयोग ज्यादातर पैसे के लिए किया जाता है ; पैसे के साथ काम करते समय बैंकर की गोलाई आम है । या आप कह सकते हैं।

यह ज्यादातर बैंकरों कि दशमलव प्रकार की जरूरत है; इसलिए यह "बैंकर की गोलाई" करता है

राउंडिंग करने वाले बैंकरों को यह फायदा होता है कि औसतन आपको वही परिणाम मिलेंगे जो आप:

  • उन्हें जोड़ने से पहले "इनवॉइस लाइनों" का एक सेट गोल करें,
  • या उन्हें जोड़ दें तो कुल मिलाकर गोल

जोड़ने से पहले राउंडिंग ने कंप्यूटर से पहले के दिनों में बहुत काम बचाया।

(यूके में जब हम गए तो दशमलव बैंक आधे पेंस से नहीं निपटेंगे, लेकिन कई वर्षों के लिए अभी भी आधा पेंस का सिक्का था और दुकान में अक्सर आधे पेंस में समाप्त होने वाले मूल्य थे - इसलिए बहुत सारे गोलाई में)


8
"दशमलव का उपयोग ज्यादातर पैसे के लिए किया जाता है" ... और सब कुछ जो एक पूर्णांक नहीं है।
जॉन टायर्री

3
@JohnTyree, जब एक पूर्णांक नहीं होता है तो अधिकांश समय डबल / फ्लोट का उपयोग नहीं किया जाता है। देखें stackoverflow.com/questions/2545567/…
इयान रिंगरोज़

3
वाह। मेरी ओर से हास्यास्पद गलती। Decmialएस, हाँ। दशमलव, नहीं। पोस्टरिटी के लिए, मैं यहां मूल भावना से सहमत हूं।
जॉन टायर्री

बैंकरों को बैंकरों की गोलाई पसंद हो सकती है, लेकिन बहीखाता वाले इसके प्रशंसक नहीं हो सकते हैं, वे कहते हैं कि 0.005 के अंतर में राउंड लीड को 0.01 से राउंड अप करना चाहिए, न कि यह विषम या समान संख्या के आधार पर।
जस्टअमार्टिन

0

इस तरह के दौर समारोह का एक और अधिभार का उपयोग करें:

decimal.Round(2.5m, 0,MidpointRounding.AwayFromZero)

यह आउटपुट 3 होगा । और अगर आप उपयोग करते हैं

decimal.Round(2.5m, 0,MidpointRounding.ToEven)

आपको बैंकर की गोलाई मिलेगी।


4
यह इस प्रश्न का उत्तर नहीं देता है कि बैंकर की गोलाई को डिफ़ॉल्ट के रूप में क्यों चुना गया।
शॉर्टस्टफसुशी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.