2012-07-02 9 views
8

1.#INF क्या है और float या double पर कास्टिंग क्यों क्रैशिंग के 0 से एक विभाजन को रोकता है?
इसके अलावा, 0 से विभाजन को रोकने के तरीके के बारे में कोई भी महान विचार? (किसी भी मैक्रो या टेम्पलेट की तरह)?शून्य रोकथाम से विभाजित

int nQuota = 0; 

int nZero = 3/nQuota; //crash 
cout << nZero << endl; 

float fZero = 2/nQuota; //crash 
cout << fZero << endl; 

अगर मैं बजाय का उपयोग करें:

int nZero = 3/(float)nQuota; 
cout << nZero << endl; 
//Output = -2147483648 

float fZero = 2/(float)nQuota; 
cout << fZero << endl; 
//Output = 1.#INF 
+2

वाह दिलचस्प। एक जवाब के लिए तत्पर हैं। –

+0

यह आपके लिए दिलचस्प हो सकता है: http://blog.regehr.org/archives/721 – cppanda

उत्तर

12

1.#INF सकारात्मक अनंत है। जब आप एक सकारात्मक फ्लोट को शून्य से विभाजित करते हैं तो आप इसे प्राप्त करेंगे (यदि आप फ्लोट शून्य को शून्य से विभाजित करते हैं, तो परिणाम "संख्या नहीं" होगा)।

दूसरी ओर, यदि आप शून्य से एक पूर्णांक विभाजित करते हैं, तो प्रोग्राम क्रैश हो जाएगा।

कारण float fZero = 2/nQuota; क्रैश कारण है क्योंकि / ऑपरेटर दोनों ऑपरेटरों पूर्णांक हैं, इसलिए विभाजन पूर्णांक पर किया जाता है। इससे कोई फर्क नहीं पड़ता कि आप परिणाम को एक फ्लोट में स्टोर करते हैं; सी ++ में लक्ष्य टाइपिंग की कोई धारणा नहीं है।

क्यों एक पूर्णांक में सकारात्मक अनंतता कास्ट सबसे छोटा पूर्णांक है, मुझे कोई जानकारी नहीं है।

+0

-2147483648 के बारे में क्या? –

+1

-2147483648 1. # आईएनएफ एक पूर्णांक के लिए डाला गया है। –

+3

सी spec 'NaN' या एक अनंत फ्लोट मान को एक पूर्णांक में परिवर्तित करने के परिणाम निर्दिष्ट करने के लिए प्रकट नहीं होता है। "अगर फ्लो ओटिंग वैल्यू नाइट या नाइन में है या यदि फ्लो ओटिंग वैल्यू का अभिन्न अंग पूर्णांक प्रकार की सीमा से अधिक है, तो 'अमान्य' 'fl oating-point अपवाद उठाया जाता है और परिणामी मान अनिश्चित है।" – mkb

1

आप आमतौर पर यह सुनिश्चित करने के लिए जांचते हैं कि आप शून्य से विभाजित नहीं हो रहे हैं। नीचे दिए गए कोड विशेष रूप से उपयोगी है जब तक कि nQuota एक वैध मूल्य है, लेकिन यह दुर्घटनाग्रस्त 0 द्वारा (नाव) या (डबल) एक प्रभाग उपयोग करने से रोकती दुर्घटनाओं

int nQuota = 0; 
int nZero = 0; 
float fZero = 0; 
if (nQuota) 
    nZero = 3/nQuota; 
cout << nZero << endl; 

if (nQuota) 
    fZero = 2/nQuota; 
cout << fZero << endl; 
+0

किंडा सरल है, लेकिन यह एक आकर्षण की तरह है। –

3

Wwhy रोकने करता है नहीं है?

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

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

इसके अलावा, 0 से विभाजन को रोकने के तरीके के बारे में कोई भी महान विचार है?

  1. सरल जवाब: ऐसा मत करो।
    यह उन लोगों में से एक है "डॉक्टर, डॉक्टर जब दर्द होता है तो दर्द होता है!" स्थितियों के प्रकार। तो ऐसा मत करो!

  2. सुनिश्चित करें कि divisor शून्य नहीं है।
    उपयोगकर्ता इनपुट वाले divisors पर सैनिटी चेक करें। हमेशा स्वच्छता के लिए अपने उपयोगकर्ता इनपुट फ़िल्टर करें। लाखों में संख्या होने पर शून्य का उपयोगकर्ता इनपुट मान ओवरफ़्लो के अलावा सभी प्रकार के विनाश का कारण बनता है। मध्यवर्ती मूल्यों पर सैनिटी चेक करें।

  3. फ़्लोटिंग पॉइंट अपवाद सक्षम करें।
    गैर-जांच के माध्यम से त्रुटियों को अनुमति देने के लिए डिफ़ॉल्ट व्यवहार करना (और ये लगभग हमेशा त्रुटियां हैं) आईएमएचओ मानक समिति के हिस्से पर एक बड़ी गलती थी।डिफ़ॉल्ट का उपयोग करें और उन infinities और संख्याओं को अंततः सब कुछ एक इंफ या एक NaN में बदल जाएगा।
    डिफ़ॉल्ट रूप से 1.0/0.0 और 0.0/0.0 जैसी चीजों को अनुमति देने के विकल्प के साथ, उनके ट्रैक में फ़्लोटिंग पॉइंट त्रुटियों को रोकने के लिए डिफ़ॉल्ट होना चाहिए था। ऐसा नहीं है, इसलिए आपको उन जाल को सक्षम करना होगा। ऐसा करें और आप बार-बार समस्या के कारण को कम क्रम में ढूंढ सकते हैं।

  4. कस्टम विभाजन, कस्टम गुणा, कस्टम वर्ग रूट, कस्टम साइन, ... लिखें लिखें।
    दुर्भाग्य से वह मार्ग है जो कई सुरक्षा महत्वपूर्ण सॉफ्टवेयर सिस्टम लेना चाहिए। यह शाही दर्द है। विकल्प # 1 बाहर है क्योंकि यह सिर्फ इच्छापूर्ण सोच है। विकल्प # 3 बाहर है क्योंकि सिस्टम को क्रैश करने की अनुमति नहीं दी जा सकती है। विकल्प # 2 अभी भी एक अच्छा विचार है, लेकिन यह हमेशा काम नहीं करता है क्योंकि खराब डेटा में हमेशा चुपके का एक तरीका होता है। यह मर्फी का कानून है।

बीटीडब्लू, समस्या सिर्फ शून्य से विभाजन से थोड़ा खराब है। 10 /10 -200 भी बह जाएगा।

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