2016-08-15 7 views
5

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

मैं निम्नलिखित कोड बनाने के लिए चाहते हैं एक अपवाद फेंक:

decimal almostMax = Decimal.MaxValue - 1; 
decimal x = almostMax + 0.1m; // This should create an exception, since x equals almostMax. 
Assert.AreEqual(x, almostMax); // This does NOT fail. 

यह वास्तव में वास्तविक कोड में कोई फर्क नहीं पड़ता है, लेकिन यह सुरक्षित है अच्छा होगा।

+0

दशमलव में 28 अंकों की सटीकता है (कुछ, लेकिन सभी नहीं, मूल्यों में 2 9 अंक हो सकते हैं)। दशमलव के रूप में। मैक्सवेल्यू 28 गीगाइट संख्या है, जो 0.1 मीटर दशमलव की परिशुद्धता से अधिक है, यही कारण है कि दो मान बराबर हैं और सम्मिलन विफल नहीं होता है। – PaulF

+2

@ पॉलफ, मुझे लगता है कि ओपी को इसके बारे में पता है। वह रनटाइम के दौरान इस समस्या का पता लगाने के लिए एक रास्ता तलाश रहा है। –

+0

कृपया ध्यान रखें कि एक अपवाद हेवीवेट ऑपरेशन है और केवल उन चीज़ों के लिए उपयोग किया जाना चाहिए जो नहीं होना चाहिए। यदि ऐसा लगता है कि कुछ गणना विफल हो जाएंगी, तो आपको "TryParse" जैसे पैटर्न का उपयोग करना चाहिए जो फेंकने के बजाए बूलियन लौटाता है और बहुत तेज़ होगा। – Lukos

उत्तर

3

इस विस्तार विधि की मदद करनी चाहिए बनाने के लिए और ओवरलोड सकता है। यह ऑपरेशन को उलट देता है और जांच करता है कि इनपुट तर्कों को परिणाम से सही तरीके से गणना की जा सकती है या नहीं। यदि ऐसा नहीं है तो ऑपरेशन ने सटीक नुकसान का कारण बना दिया।

कार्य उदाहरण: https://dotnetfiddle.net/vx6UYY

आप आदि + की तरह नियमित रूप से ऑपरेटरों का उपयोग करना चाहते हैं, तो आप Philipp Schmid's solution के साथ जाने के लिए और अपने खुद दशमलव प्रकार पर ऑपरेटरों को लागू करने की है।

+1

सावधान हालांकि, यह जांच नहीं करता कि परिणाम सटीक है। '11m' जोड़ने का प्रयास करते समय, यदि' 10m' इसके बजाय जोड़ा जाता है, तो यह विधि अपवाद नहीं फेंकती है। '(परिणाम - ए! = बी || परिणाम - बी! = ए) 'इसे कवर करना चाहिए, अगर मैं किसी विशेष मामले को नहीं देख रहा हूं। – hvd

+0

@ एचवीडी, अच्छा बिंदु! मैंने ठीक कर दिया। –

+0

यह एक अच्छा है जो प्रदर्शन स्तर को उचित स्तर पर भी रख सकता है। – Andreas

0

आप एक SaveDecimal वर्ग + ऑपरेटर
https://msdn.microsoft.com/en-us/library/aa288467%28v=vs.71%29.aspx

public class SafeDecimal 
{ 
    private decimal DecValue; 

    public SafeDecimal(decimal Value) 
    { 
     DecValue = Value; 
    } 

    public decimal GetValue() 
    { 
     return DecValue; 
    } 

    public static SafeDecimal operator +(SafeDecimal A, SafeDecimal B) 
    { 
     decimal almostMax = Decimal.MaxValue - 1; 

     checked 
     { 
      if (almostMax <= A.GetValue() + B.GetValue()) 
       throw new Exception("----scary error message----"); 
     } 

     return new SafeDecimal(A.GetValue() + B.GetValue()); 
    } 
} 
+1

क्या यह नकारात्मक मूल्यों को ध्यान में रखता है? – zerkms

+0

नहीं, यह नहीं है। मुझे शायद इसे ठीक करना चाहिए, धन्यवाद। –

+1

सी # पहले से ही arithemtic संचालन के लिए अतिप्रवाह संरक्षण प्रदान करता है (इस उदाहरण को देखें: http://csharppad.com/gist/7f4edd08bde1061201ca13dca9332806)। आप पहले से मौजूद कुछ ऐसा फिर से कार्यान्वित कर रहे हैं, साथ ही प्रश्न परिशुद्धता-हानि के बारे में नहीं था। हालांकि समाधान का सामान्य विचार ठीक लगता है। बस कोड को बदलें ताकि ओपी द्वारा निर्दिष्ट शर्तों के तहत '+' अपवाद फेंकता हो और यह उत्तर अच्छा आईएमओ है। –

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