2012-08-04 11 views
9

हम कैसे जांच सकते हैं कि अंकगणितीय ऑपरेशन वास्तव में इसे लागू करने से पहले डेटा प्रकार की ऊपरी सीमाओं से अधिक होगा या नहीं।अंकगणितीय परिचालनों के लिए ओवरफ़्लो और रेंज जांच

जावा में छोटे के लिए upperbound कहते हैं कि मैं वास्तव में क्योंकि के बाद गुणा जवाब पहले से ही बहकर किया जाएगा और इस सवाल का जवाब -32,736 जो निश्चित रूप से छोटे से Short.MAX_VALUE

है किया जाएगा Short.MAX_VALUE के साथ तुलना नहीं कर सकते 32767 है और मैं 328 * 100 गुणा कर रहा हूँ,

एक और उदाहरण लें कि मैं int एक लूप में 17^10 (17 शक्ति के लिए 17) कंप्यूटिंग का मूल्य हूं। मुझे कैसे पता चलेगा कि मेरा जवाब किस स्तर पर बह गया है।

यह Short और int बात सिर्फ एक उदाहरण है। इस समस्या को बड़े समझने में सोचें कि सभी डेटा प्रकारों के लिए वास्तव में क्या किया जा सकता है।

मैंने googling की कोशिश की लेकिन कोई अच्छा लिंक नहीं मिला जो अवधारणा को समझने में मदद करता है।

एक बड़ा प्रकार और खिन्न का उपयोग करें:: अगले बड़े आदिम पूर्णांक प्रकार के इनपुट कास्ट और बड़े आकार में अंकगणित को निष्पादित

+0

क्या आप चेतावनियां चाहते हैं? क्या आप अतिप्रवाह संख्या संतृप्त होना चाहते हैं? क्या आप इसे निष्पादन रोकना चाहते हैं? कोशिश करें {} पकड़ (integeroverflow) {} सहायक होना चाहिए –

+0

@ tuğrulbüyükışık कोशिश-पकड़ यहां तस्वीर में नहीं आती है, अगर अपवाद फेंक दिया गया तो प्रोग्राम वहां और फिर ही रुक जाएगा। – Harshdeep

+1

रुक गया नहीं है लेकिन हां –

उत्तर

4

जावा 8 में मैथ पैकेज में ऐसी विधियों को शामिल करने की एक योजना है, लेकिन मुझे नहीं पता कि वर्तमान स्थिति क्या है। कुछ स्रोत कोड here उपलब्ध है। मैं कार्यान्वयन का परीक्षण नहीं करता हूं, लेकिन यह आपको विचार दे सकता है। ,

public static long multiplyExact(long x, long y) { 
    long r = x * y; 
    long ax = Math.abs(x); 
    long ay = Math.abs(y); 
    if (((ax | ay) >>> 31 != 0)) { 
     // Some bits greater than 2^31 that might cause overflow 
     // Check the result using the divide operator 
     // and check for the special case of Long.MIN_VALUE * -1 
     if (((y != 0) && (r/y != x)) || 
      (x == Long.MIN_VALUE && y == -1)) { 
      throw new ArithmeticException("long overflow"); 
     } 
    } 
    return r; 
} 
+1

यह थोड़ा दिलचस्प लगता है। धन्यवाद @ वासिलियास। मैं यह देखने के लिए इंतजार करूंगा कि किसी के पास कोई और सुझाव है या नहीं, मैं आपका उत्तर चुनूंगा। – Harshdeep

5

अतिप्रवाह जांच के लिए 3 संभव तरीकों रहे हैं। मूल छोटे प्रकार के अतिप्रवाह के लिए प्रत्येक मध्यवर्ती परिणाम की जांच करें; रेंज चेक विफल होने पर एक अंकगणितीय अपवाद फेंक दें।

प्री-चेक इनपुट: प्रत्येक अंकगणितीय ऑपरेटर को इनपुट जांचें ताकि यह सुनिश्चित किया जा सके कि अतिप्रवाह नहीं हो सकता है। ऑपरेशन खत्म होने पर ऑपरेशन ओवरफ्लो होने पर फिर से एक अंकगणितीय अपवाद फेंक दें, अन्यथा ऑपरेशन करें।

उदा .:

static void preAddCheck(int left, int right) throws ArithmeticException { 
    if (right > 0 ? left > Integer.MAX_VALUE - right : left < Integer.MIN_VALUE - right) { 
    throw new ArithmeticException("Integer overflow"); 
    } 
} 

BigInteger: प्रकार BigInteger की वस्तुओं में आदानों कन्वर्ट और BigInteger तरीकों का उपयोग कर सभी गणित प्रदर्शन करते हैं। अंकगणित अपवाद अतिप्रवाह पर फेंक दिया।

+1

यह प्रश्न 'प्री-चेक इनपुट' के बारे में है। मैं उसे कैसे कर सकता हूँ। मैं नहीं जानता कि इससे पहले कि मैं वास्तव में ऑपरेशन करता हूं। तो कम से कम उस सुझाव से इंकार कर दिया गया है। – Harshdeep

+0

यह आपके द्वारा किए जाने वाले संचालन (ओं) पर निर्भर करेगा। मैंने अतिरिक्त के लिए एक चेक जोड़ा। – Reimeus

2

मैं गणना सबसे बड़ा संभव प्रकार का उपयोग करना चाहते हैं:

उदाहरण के लिए, पूर्णांक गुणन देशांतर का उपयोग करके किया जाता है:

public static int multiplyExact(int x, int y) { 
    long r = (long)x * (long)y; 
    if ((int)r != r) { 
     throw new ArithmeticException("long overflow"); 
    } 
    return (int)r; 
} 

लेकिन लंबे गुणा एक अधिक जटिल एल्गोरिथ्म का उपयोग करता BigInteger/BigDecimal। इसके बाद मैं इसके आयाम के आधार पर उचित प्रकार के मान को असाइन करूँगा ... दिलचस्प बात यह है कि इसके लिए कुछ उपयोगी तरीके हैं ... shortValueExtract एक अंकगणित अपवाद फेंक देगा यदि मान को संक्षेप में निहित नहीं किया जा सकता है ..

BigDecimal result = BigDecimal.valueOf(328).multiply(
     BigDecimal.valueOf(100)); 
try { 
    short shortResult = result.shortValueExact(); 
} catch (ArithmeticException e) { 
    // overflow 
    System.out.println("Overflow!"); 
} 

try { 
    int intResult = result.intValueExact(); 
} catch (ArithmeticException e) { 
    // overflow 
} 
संबंधित मुद्दे