2010-02-13 13 views
13

द्वारा विभाजन के लिए कोशिश पकड़ मैं एक जावा नौसिखिया हूँ, मेरे सवाल के बारे में की कोशिश-पकड़ है शून्य उदाहरण के द्वारा एक सरल विभाजन पर ब्लॉक। आप कोशिश की पहली पंक्ति देखते हैं? यदि मैं दो में से किसी भी दो चर को कास्ट करता हूं तो प्रोग्राम कैच ब्लॉक को नहीं पहचानता है। मेरी राय में, चाहे मैंने डाला या न केवल पकड़ ब्लॉक को निष्पादित किया जाना चाहिए। इस कोड पर क्या गलत है? धन्यवाद।शून्य

public static void main(String[] args) { 

    int pay=8,payda=0; 

    try { 

     double result=pay/(double)payda; // if I cast any of the two variables, program does not recognize the catch block, why is it so? 
     System.out.println(result); 
     System.out.println("inside-try"); 


    } catch (Exception e) { 

     System.out.println("division by zero exception"); 
     System.out.println("inside-catch"); 

    } 
} 

उत्तर

22

शून्य से विभाजित फ्लोटिंग पॉइंट नंबरों के लिए मान्य है।

  • 1/0 इन्फिनिटी पैदा करता है।
  • (-1)/0 उपज-अनंतता।
  • 0/0 उपज NaN।

ये "संख्या" ठीक से, शून्य से आईईईई 754

पूर्णांक प्रभाग में परिभाषित कर रहे हैं तो दूसरी ओर, फेंकता है, क्योंकि एक एक int के रूप में अनंत का प्रतिनिधित्व नहीं कर सकते हैं।

+0

यदि फ़्लोटिंग पॉइंट डिवीजन अपवाद नहीं फेंक सकता है, तो कोशिश/पकड़ हटा दिया जाना चाहिए और इसके बजाय त्रुटि कोड का उपयोग किया जाना चाहिए। –

+1

मुझे नहीं लगता कि 'int' फेंकता है क्योंकि यह अनंतता का प्रतिनिधित्व नहीं कर सकता है। 1/0 बस अर्थहीन है, और यही कारण है कि यह फेंकता है। दूसरी तरफ, फ़्लोटिंग प्वाइंट ने कुछ हाथ से लहराया और कहा "यह अनंत होना चाहिए"। – GManNickG

3

जवाब अपने कार्यक्रम के लिए अपने उत्पादन में निहित है - यह result के लिए "इन्फिनिटी" प्रिंट करता है। ऐसा इसलिए है क्योंकि जावा केवल शून्य द्वारा पूर्णांक विभाजन को अस्वीकार करता है - शून्य द्वारा फ़्लोटिंग पॉइंट डिवीजन कानूनी है और Infinity का उत्पादन करता है।

POSITIVE_INFINITY और NEGATIVE_INFINITY स्थिरांक के लिए Double और Float के दस्तावेज़ देखें।

14

मैं पुष्टि करने का सुझाव चाहते हैं:

if (divisor != 0) { 
    // calculate 
} 

बल्कि एक अपवाद

+0

जब तक विभाजक पूर्णांक नहीं होता है, गैर-शून्य विभाजक आसानी से अनुपयोगी परिणाम उत्पन्न कर सकते हैं, जैसे एक बड़े denom और छोटे divisor: "डबल div = Double.MAX_VALUE/0.5;" अनंतता पैदा करता है। मैं divisor की जांच करने पर किसी भी जोखिम भरा गणना पर Double.isInfinite और Double.isNaN (या फ़्लोट समकक्ष) की जांच करने की अनुशंसा करता हूं! = 0. –

+0

धारणा वे पूर्णांक हैं, उदाहरण के उदाहरण – Bozho

1

क्योंकि दो युगल विभाजित रिटर्न एक इन्फिनिटी, लेकिन फेंक नहीं है पकड़ने से। आप इसे देखने के लिए isInfinite() का उपयोग कर सकते हैं। हालांकि, उचित समाधान (जैसा कि पहले से ही उल्लेख किया गया है) विभाजन से पहले denominator की जांच है।

+0

से ऊपर उदाहरण में केवल एक NaN लौटाता है यदि तर्क में से एक NaN है या दोनों अनंत हैं या दोनों शून्य हैं। शून्य से एक nonzero विभाजित - सवाल - सकारात्मक या नकारात्मक अनंतता में परिणाम। http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#15.17.2 –

2

केवल पूर्णांकों के साथ शून्य से भाग एक ArithmeticException बढ़ा देंगे। डबल या फ्लोट के साथ शून्य से डिवीजन परिणामस्वरूप इन्फिनिटी होगा।

7

चूंकि आप एक स्वयंभू "नौसिखिया" कर रहे हैं, मुझे लगता है कि यह एक अच्छा विचार अपने कोड के साथ कुछ व्यापक मुद्दों का कहना होगा। (मैं इसे उत्पादन कोड नहीं है, लेकिन सिर्फ तर्क है कि यह था की खातिर मान देता है।)

  • एक अपवाद की उम्मीद है, तो यह आम तौर पर, सरल स्पष्ट और अधिक कुशल है अगर आप हालत का पता लगाने के जो अपवाद को जन्म देगा। इस मामले में, यदि आप कभी-कभी शून्य होने के लिए divisor की अपेक्षा करते हैं तो विभाजन करने से पहले इसका परीक्षण करना बेहतर होता है।

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

  • अलावा पिछले बुलेट से, यह एक बुरा विचार Exception, RuntimeException, Throwable या Error को पकड़ने के लिए है। ऐसा करने से बड़ी संख्या में अपवाद होंगे जो आप शायद पकड़ने का इरादा नहीं रखते हैं।इस मामले में, चूंकि आप ArithmeticException की अपेक्षा कर रहे हैं, तो आपको बस इसे पकड़ना चाहिए।

  • वित्तीय अनुप्रयोगों में float या double का उपयोग करना शायद ही कभी सही है। ये प्रकार सटीक नहीं हैं, लेकिन वित्तीय अनुप्रयोगों को आम तौर पर संभालने के लिए धन की मात्रा की आवश्यकता होती है।

  • अधिक आम तौर पर, फ़्लोटिंग पॉइंट नंबर लोगों (और नए शौक) को समझने के लिए स्वाभाविक रूप से कठिन होते हैं। बहुत से "सच्चाई" जो लोग वास्तव में पकड़ने की उम्मीद करते हैं, वे वास्तव में नहीं पकड़ते हैं। उदाहरण के लिए, 1.0/3.0 + 1.0/3.0 + 1.0/3.0 की फ़्लोटिंग पॉइंट गणना 1.0 नहीं देती है। इसी प्रकार (जैसा कि आपने पाया) शून्य से विभाजन अलग-अलग व्यवहार करता है। यदि आप सुरक्षित रूप से फ़्लोटिंग पॉइंट का उपयोग करना चाहते हैं, तो आपको नुकसान को समझने की आवश्यकता है।

संपादित @ जे की टिप्पणी के जवाब में पहला बिंदु व्याख्या।

सबसे पहले, मैंने जानबूझकर "आमतौर पर" शब्द का उपयोग किया। ऐसे मामले हैं जहां अपेक्षित अपवाद फेंकने से बचने से कुछ भी नहीं मिलता है।

ऐसा कहकर, आप अक्सर एक सामान्य "अपेक्षित" अपवाद नहीं चाहते हैं यदि आपका एप्लिकेशन तत्काल स्थिति से निपट नहीं सकता है। उदाहरण के लिए, यदि ओपी का कोड कुछ बड़ा हिस्सा था, तो स्पष्ट रूप से IllegalArgumentException (यदि यह एपीआई अनुबंध का उल्लंघन है) को स्पष्ट रूप से फेंकना बेहतर हो सकता है या कुछ UserEnteredRubbishException चेक किया गया है, तो हम जानते हैं कि यह खराब उपयोगकर्ता इनपुट का परिणाम है (और रिपोर्ट करने/इसे सही करने का कुछ अवसर है)।

तथ्य यह है कि हम एक अपवाद की अपेक्षा कर रहे हैं परिभाषा द्वारा हम इसके बारे में अधिक जानते हैं (कहें) एक सामान्य ArithmeticException कहेंगे। अगर हम प्रचार के लिए एक सामान्य अपवाद की अनुमति देते हैं, तो यह पकड़ने के लिए कई स्टैक फ्रेम को उचित तरीके से कार्य करने के लिए कठिन बनाता है। इस मामले में उदाहरण के लिए, रिमोट कैच ब्लॉक किसी भी निश्चितता के साथ विभाजित-शून्य-शून्य के कारण का निदान नहीं कर सका। ArithmeticException एप्लिकेशन के एक अलग हिस्से से आया है, और भी विभाजित नहीं हो सकता है! संबोधित करने का तरीका स्पष्ट रूप से एक और विशिष्ट अपवाद फेंकना है।

+0

मैं आपके पहले बिंदु के साथ quibble होगा। यदि एक विशेष मामला अपेक्षित है और ऐसा कुछ है जो आप इसे संभालने और प्रसंस्करण जारी रखने के लिए कर सकते हैं, तो हाँ, आपको अपवाद फेंकने के बजाय इसकी जांच करनी चाहिए।लेकिन अगर कोई फर्क नहीं पड़ता कि कोई विशेष मामला कैसा है, तो ऐसा होने पर आप जो भी कर सकते हैं वह रोना है और युद्ध के कुत्ते को ढीला करना है, फिर बस अपवाद फेंक दें। – Jay

+0

लेकिन # 3 और # 4 पर मेगा डिटोस। एक सामान्य अपवाद पकड़ना शायद ही कभी उत्पादक है। आपको पता नहीं है कि आप क्या पकड़ रहे हैं। वैसे, मैं जोड़ सकता हूं: अनुशासनिक: सामान्य अपवाद नहीं फेंकें। यदि आपका प्रोग्राम किसी त्रुटि की स्थिति का पता लगाता है और आप अपवाद फेंकना चाहते हैं, तो इसके लिए एक नई कक्षा बनाने के लिए दस मिनट लगें जो अपवाद बढ़ाता है। न केवल 'नई अपवाद फेंकें ("फू में एक बार गायब था)" या जो भी हो। – Jay

0

किसी को भी अपने कोड से RuntimeException को फेंकने की उम्मीद नहीं करनी चाहिए। ये Exception एस आसानी से से बचा जा सकता है (और होना चाहिए)।