2016-07-25 8 views
9

बना सकता है मेरे पास एक संख्या है जो शून्य हो सकती है। मैं उस संख्या से विभाजित हूं इसलिए मैं परीक्षण करना चाहता हूं कि नाएन और अनंतता को रोकने के लिए शून्य है या नहीं। क्या यह संभव है कि मैं अभी भी विभाजन के भीतर त्रुटियों को गोल करने के कारण NaNs/अनंतता बना सकता हूं?गैर-शून्य द्वारा विभाजन अभी भी एक नैन/अनंतता

double x; // might be zero 
double y; 

if(x != 0) return y/x; 

संपादित

प्रतिक्रिया के लिए धन्यवाद। मैं फिर कुछ subquestions जोड़ देंगे।

1) मानते हैं कि न तो एक्स और न ही वाई NaN/+ inf या -inf है, क्या एक विभाजन होगा जिसके परिणामस्वरूप -inf/+ inf परिणामस्वरूप अधिक CPU चक्र या कोई अन्य अवांछित व्यवहार होता है? (क्या यह क्रैश हो सकता है?)

2) विभाजन से रोकने के लिए एक तरीका है जिसके परिणामस्वरूप अनंतता है? ऑफ़सेट का उपयोग करना आदि।

+0

वे अनंत या यहाँ तक कि नेन – EFenix

+2

हो सकता है 'y' पहले से ही NaN, तो परिणाम है NaN भी होगा। –

+2

किसी के पास पहले से ही एक उत्तर प्रकाशित करने के बाद और अधिक प्रश्न जोड़ना (3, इस मामले में) बहुत अच्छा नहीं है - यह उन उत्तरों को अपूर्ण दिखता है, हालांकि वे तब नहीं थे जब वे लिखे गए थे। –

उत्तर

6

बहुत छोटी संख्या में बहुत छोटी संख्या को विभाजित करना, या दो बहुत बड़ी संख्याओं के गुणा को "अनंत" उत्पन्न हो सकता है। एक और अनंतता से एक अनंतता को विभाजित करने से एक नाएन उत्पन्न होगा। उदाहरण के लिए, (1E300/1E-300)/(1E300/1E-300) या (1E300*1E300)/(1E300*1E300) दोनों NaN उत्पन्न करेंगे।

9

Can विभाजन गैर शून्य से अभी भी एक नेन/अनंत

हाँ पैदा करते हैं।

तो आईईईई-754 तो पीछा किया जाता है:

  • या तो संकार्य NaN है, परिणाम NaN हो जाएगा।
  • यदि दोनों अंक और denumerator अनंत हैं, परिणाम NaN है।
  • यदि केवल संख्यात्मक अनंत है, तो परिणाम अनंत है।
  • यदि छोटे denumerator (या बड़े संख्यात्मक) overflows द्वारा विभाजन, वर्तमान दौर मोड के आधार पर परिणाम अनंत हो सकता है।

अन्य प्रतिनिधित्वों के नियम अलग-अलग हो सकते हैं।


2) वहाँ

यह है कि को रोकने में एक लंबा रास्ता तय करना चाहिए अनंत में जिसके परिणामस्वरूप से devision को रोकने के लिए एक तरीका है:

#include <cfenv> 
#include <cassert> 
#include <cmath> 
#include <limits> 

// ... 

static_assert(std::numeric_limits<decltype(x)>::is_iec559, "Unknown floating point standard."); 
#pragma STDC FENV_ACCESS ON 
int failed = std::fesetround(FE_TOWARDZERO); 
assert(!failed); 
if(x != 0 && std::isfinite(x) && std::isfinite(y)) 
    return y/x; 
else 
    throw std::invalid_argument("informative message"); 

कुछ compilers आवश्यकता हो सकती है पूर्ण आईईईई 754 अनुपालन (-frounding-math जीसीसी पर सक्षम करने के लिए गैर-डिफ़ॉल्ट विकल्प)।

+0

"वर्तमान राउंडिंग मोड के आधार पर" यह महत्वपूर्ण है, 'fegetround'/'fesetround' देखें। यदि आप शून्य की ओर घूमते हैं, तो आप कभी भी एक inf नहीं प्राप्त कर सकते हैं यदि आप परिमित गैर-शून्य से विभाजित करते हैं। – sbabbi

+0

मुझे लगता है कि fesetround ऐसा कुछ नहीं है जिसे प्रदर्शन-संवेदनशील कार्य में बुलाया जाना चाहिए, है ना? –

+0

@ruhigbrauner संभवतः नहीं। आप इसे किसी भी हॉट लूप के बाहर ले जाना चाहते हैं। – user2079303

5

हाँ, बस कोड में नीचे

#include <iostream> 
int main() 
{ 
    double x = 1, y = 2; 
    while (y != 0) { 
     std::cout << y << " " << x/y << std::endl; 
     y /= 2; 
    } 
} 

कुछ पल को देखने के आप मिल जाएगा:

8.9003e-308 1.12356e+307 
4.45015e-308 2.24712e+307 
2.22507e-308 4.49423e+307 
1.11254e-308 8.98847e+307 
5.56268e-309 inf 
2.78134e-309 inf 
1.39067e-309 inf 
6.95336e-310 inf 
संबंधित मुद्दे