2009-09-16 8 views
7

ग्रहण आईडीई का उपयोग कर जावा कोड में संभावित संख्यात्मक अतिप्रवाह खोजने का कोई तरीका है? उदाहरण के लिए ...ग्रहण का उपयोग करते हुए, जावा कोड में संभावित संख्यात्मक अतिप्रवाह कैसे प्राप्त करें?

long aLong = X * Y * Z; 

... जहां एक्स, Y, और Z ints कर रहे हैं और परिणाम Integer.MAX_VALUE अतिप्रवाह हो सकता है। (ध्यान दें, शायद काउंटर-इंट्यूटिवली, अगर इस उदाहरण में परिणाम Integer.MAX_VALUE ओवरफ्लो हो जाता है, तो एलोन को गलत ओवरफ्लोल्ड वैल्यू असाइन किया जाएगा)।

मैंने ग्रहण की चेतावनी सेटिंग्स, पीएमडी नियम, और FindBugs नियमों में देखा है और मुझे इसके साथ मदद करने के लिए कोई सेटिंग नहीं मिल रही है। एक सहकर्मी नोट करता है कि इंटेलिजे इस बारे में चेतावनी देगा ... और मुझे यह स्वीकार करना होगा कि मैं ग्रहण के साथ ऐसा नहीं कर सकता। ;-)


स्पष्टीकरण 1:। मैं कुछ है कि 0 झूठे सकारात्मक ... बस चेतावनी "आप एक अतिप्रवाह समस्या यहाँ हो सकता है" कि,

स्पष्टीकरण 2 देता है के लिए नहीं देख रहा हूँ: यह पर "विकास समय" ... अर्थ वांछित है, एक ही स्तर पर है कि ग्रहण अप्रयुक्त आयात की तलाश में है, PMD अपने नियमों में जाँच कर रहा है, आदि

+0

तो क्या आप किसी भी अंकगणितीय ऑपरेशन की चेतावनी देना चाहते हैं? ए = एक्स + वाई ओवरफ्लो हो सकता है यदि एक्स, एक्स और वाई एक ही अभिन्न प्रकार – Mark

+0

हैं, तो मैं भी इस तरह की जांच करना चाहता हूं, लेकिन केवल गुणा के लिए। मैं प्रतियोगिता प्रोग्रामिंग कर रहा हूं और आम तौर पर मान 10^9 तक हैं, इसलिए अतिरिक्त कोई समस्या नहीं है, लेकिन गुणा है और मैं चेतावनी देना चाहता हूं, अन्यथा मैं '1L * x * y' चाल भूल जाता हूं ... – Betlista

उत्तर

-1

आप java.math.BigInteger के साथ अपने गणना करते हैं और साथ परिणाम की तुलना कर सकते हो सकता है

new java.math.BigInteger(String.valueOf(Long.MAX_VALUE)) 
+0

त्रुटियों के बिना गणना करने का एक तरीका है, लेकिन यह पता लगाने के लिए कि क्या गणना किसी विशेष प्रकार की त्रुटि के अधीन है, जो प्रश्न पूछ रहा है। – Carl

0

आप इसे संकलित समय पर चाहते हैं? ऐसा करने के लिए एक सेटिंग नहीं देखी है।

यदि आप वास्तव में चाहते हैं, तो सबसे अच्छा शर्त पीएमडी के लिए एक नया नियम लिखने की संभावना है?

0

इसके लिए अपेक्षित परिणाम क्या होगा?

long testMethod() { 
    long aLong = Integer.MAX_VALUE + doesMethodContainAnOverflow ("testMethod") ? 0 : 1; 

    return aLong; 
} 

इसमें केवल ओवरफ़्लो है यदि इसमें कोई ओवरफ़्लो नहीं है।

किसी भी निश्चित प्रतिनिधित्व पूर्णांक ऑपरेशन के लिए संभावित ओवरफ़्लो है; यह निर्धारित करना कि क्या वास्तविक ओवरफ्लो रोकथाम की समस्या के लिए तुच्छ रूप से परिवर्तनीय है या नहीं। जिसका अर्थ यह नहीं है कि इंटेलिजे के पास कुछ मामलों में आपको चेतावनी देने के लिए कुछ ह्युरिस्टिक नहीं है - उदाहरण के लिए, आप किसी प्रोग्राम के माध्यम से किसी भी संख्यात्मक संचालन के ऊपरी और निचले सीमाओं को ट्रैक कर सकते हैं और सबसे खराब केस जवाब प्राप्त कर सकते हैं, लेकिन एक लिखना सटीक नियम न तो तुच्छ और न ही निर्णायक होगा।

+0

प्रश्न * संभावित * अतिप्रवाहों के लिए है, जो सबसे खराब मामला जवाब है, जैसा कि आप इंगित करते हैं, निर्णायक है। यह सुविधा किसी भी तरह से ओवरफ्लो का निर्णय लेने के बारे में नहीं है, यह उन चीजों पर ध्यान देने की तरह है जो प्रोग्रामर संभावित ओवरफ्लो पॉइंट्स के रूप में पहचाना नहीं गया हो सकता है, हालांकि शोर शायद बहुत अधिक है (चरम पूर्णांक का सरल जोड़ इसे बंद करना चाहिए, उदाहरण के लिए)। – Carl

+0

कोई पढ़ रहा है जीईबी – Jherico

0

या तो इसे एल्गोरिदम के गहरे एनालिसिस की आवश्यकता होगी या आपको प्रत्येक अंकगणितीय ऑपरेशन के लिए चेतावनी दी जाएगी जिसमें चर शामिल हैं।

संपादित करें: ओह, क्या आपका मतलब है कि यदि एक्स, वाई और जेड पूर्णांक हैं, तो गुणा पूर्णांक पर होगा और केवल तब तक आवंटित किया जाएगा? IntelliJ आइडिया इसे एक चेतावनी के रूप में दिखाएगा लेकिन निरीक्षण डिफ़ॉल्ट रूप से बंद है।

+0

हां, आपका EDIT सही है। मैं सिर्फ इंटेलिजे आइडिया के समान चेतावनी की तलाश में हूं। – dirtyvagabond

+0

आप FindBugs नियम का पीएमडी लिख सकते हैं, लेकिन मुझे नहीं लगता कि यह इसके लायक है। –

1

FindBugs में FindPuzzlers डिटेक्टर के विवरण

ICAST_INTEGER_MULTIPLY_CAST_TO_LONG (iCast, शैली) शामिल हैं: लंबे

को पूर्णांक गुणन कलाकारों का परिणाम है, लेकिन किसी भी तरह मैं इस निम्नलिखित कोड में समस्या का पता लगाने के नहीं बना सकते:

final int x = 10000; 
    final int y = 10000; 
    final int z = 10000; 
    final long aLong = x * y * z; 
    System.out.println(aLong); 
+0

एक्लिप्स प्लगइन में दो सेटिंग्स हैं - "रिपोर्ट करने के लिए न्यूनतम रैंक" और "रिपोर्ट करने के लिए न्यूनतम विश्वास"। इसमें रैंक 17 है और जब दिखाया जाता है कि आत्मविश्वास कम या मध्यम पर सेट होता है ... – Betlista

4

यदि आपको नहीं पता कि एक्स क्या हो सकता है, तो यह सबसे खराब मामला हो सकता है।

int X = Integer.MAX_VALUE; 
long aLong = X + 1; 

निष्कर्ष:: तो, सबसे खराब स्थिति क्या है आप ग्रहण सब कुछ के बारे में चेतावनी देने के लिए नहीं करना चाहती।

आप

long aLong = X * Y * Z; //you could write 
long aLong = (long)X * Y * Z; 

निष्कर्ष के पूर्णांक अतिप्रवाह ठीक करने के लिए करना चाहते हैं: यह लंबे समय अतिप्रवाह समस्याओं को ठीक नहीं होगा। यदि आप उन्हें ठीक करना चाहते हैं तो आपको कोड लिखना चाहिए:

BigInteger tmp = BigInteger.valueOf(X).multiply(BigInteger.valueOf(Y)).multiply(BigInteger.valueOf(Z)); 
if(BigInteger.valueOf(Long.MAX_VALUE).compareTo(tmp)>=0){ 
    long aLong = tmp.longValue(); 
}else{ 
    System.out.println("Overflow"); 
} 

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

यदि आप ग्रहण के लिए एक उपकरण लिखना चाहते हैं जो इसे खोजने के लिए संपूर्ण स्रोत फ़ाइल को पार करता है, तो मैं आपको रोक नहीं रहा हूं। लेकिन यह निम्नलिखित मानों को याद रखना बहुत आसान होगा:

/*11111111111111111111111111111111*/int Y = -1; //-1 
/*11111111111111111111111111111111*/int QRY = (Y >> 1); //-1 
/*11111111111111111111111111111110*/int QLY = (Y << 1); //-2 
/*11111111111111111111111111111110*/int QLX = (X << 1); //-2 
/*11000000000000000000000000000000*/int QRZ = (Z >> 1); //-1073741824 
/*10000000000000000000000000000000*/int Z = Integer.MIN_VALUE; //-2147483648 
/*01111111111111111111111111111111*/int X = Integer.MAX_VALUE; // 2147483647 
/*00111111111111111111111111111111*/int QRX = (X >> 1); // 1073741823 
/*00000000000000000000000000000000*/int QLZ = (Z << 1); // 0 
संबंधित मुद्दे