2008-10-24 14 views
31

सबसे अच्छा तरीका है सी ++ में Nans उपयोग करने के लिए क्या है?सी ++ में NaN का उपयोग करना?

मैं std::numeric_limits<double>::quiet_NaN() और std::numeric_limits<double>::signaling_NaN() पाया। मैं signaling_NaN उपयोग करने के लिए इस प्रकार है एक गैर-आरंभिकृत चर का प्रतिनिधित्व करना चाहते हैं:

double diameter = std::numeric_limits<double>::signaling_NaN(); 

लेकिन यह संकेत काम पर (एक अपवाद को जन्म देती है)। मैं इसे असाइनमेंट पर नहीं, उपयोग पर अपवाद उठाना चाहता हूं।

वहाँ किसी भी तरह से काम पर एक अपवाद को ऊपर उठाने के बिना signaling_NaN उपयोग करने के लिए है? वहाँ signaling_NaN है कि एक चल बिन्दु अपवाद बढ़ा देंगे के लिए एक अच्छा, पोर्टेबल विकल्प जब इस्तेमाल किया है? (एनबी: अपरीक्षित)

+0

हम्म ... मैं इसके साथ खेल रहा हूं क्योंकि अब मैं उत्सुक हूं लेकिन मुझे अपवाद बढ़ाने के लिए मेरा नहीं मिल सका। अपवाद पाने के लिए आपने क्या किया? –

+0

@ जेफरीमार्टिनेज यह सामान्य सी ++ अपवाद नहीं है, अगर आप यही सोच रहे हैं। यह एक फ़्लोटिंग पॉइंट अपवाद है: नोट्स [यहां] देखें (http://en.cppreference.com/w/cpp/numeric/fenv)। – bames53

उत्तर

11

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

Menkboy's code काम करता है, लेकिन Nans संकेत का उपयोग करने की कोशिश कर अन्य समस्याओं में चलाता है: वहाँ सक्षम या चल बिन्दु अपवाद (के रूप में here और here उल्लेख) को निष्क्रिय करने के लिए कोई पोर्टेबल तरीका है, और यदि आप अपवाद पर भरोसा कर रहे हैं सक्षम किया जा रहा, तीसरे पार्टी कोड उन्हें अक्षम कर सकता है (जैसा वर्णन here) है।

तो ऐसा लगता है कि Motti's solution वास्तव में सबसे अच्छा विकल्प है।

3

आप कुछ इस तरह के साथ एक अपवाद ट्रिगर किए बिना एक चर में एक संकेत NaN लिख सकते हैं

void set_snan(double &d) 
{ 
    long long *bits = (long long *)&d; 
    *bits = 0x7ff0000080000001LL; 
} 

यह सबसे अधिक स्थानों काम करेंगे, लेकिन नहीं, यह 100% पोर्टेबल नहीं है।

0

आपका सी ++ कार्यान्वयन के लिए परीक्षण करने के लिए चल बिन्दु पर्यावरण पहुँचने और स्पष्ट कुछ चल बिन्दु अपवाद के लिए एक API हो सकता है। अधिक जानकारी के लिए my answer to a related question देखें।

3

ठीक है, शांत और सिग्नलिंग NaN दोनों की परिभाषा की देखभाल के बाद, मैं वास्तव में कोई अंतर नहीं कर सकता।

आप कोड है कि उन कार्यों अपने आप में प्रयोग किया जाता है इस्तेमाल कर सकते हैं, हो सकता है यह एक अपवाद है कि जिस तरह से रोकता है, लेकिन उन दो कार्यों में कोई अपवाद नहीं दिखाई दे रहा है, मैं यह कुछ और से संबंधित हो सकती है।

आप सीधे NaN प्रदान करना चाहते हैं:

double value = _Nan._Double; 
9

क्या संकेतन नेन का मतलब यह है कि जब सीपीयू यह सामना करना पड़ता है एक संकेत, निकाल दिया जाता है (इसलिए नाम)। यदि आप अनियमित चर का पता लगाना चाहते हैं तो अपने कंपाइलर पर चेतावनी स्तर को बढ़ाने से आमतौर पर सभी पथों का पता चलता है जो अनियमित मानों का उपयोग करते हैं। विफल रहने के है कि आप एक आवरण वर्ग संग्रहीत करता है कि एक बूलियन कह यदि मान आरंभ नहीं हो जाता का उपयोग कर सकते हैं:

template <class T> 
class initialized { 
    T t; 
    bool is_initialized; 
public: 
    initialized() : t(T()), is_initialized(false) { } 
    initialized(const T& tt) : t(tt), is_initialized(true) { } 
    T& operator=(const T& tt) { t = tt; is_initialized = true; return t; } 
    operator T&() { 
     if (!is_initialized) 
      throw std::exception("uninitialized"); 
     return t; 
    } 
}; 
+4

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

3

सरल जवाब: हेडर फाइल में कुछ इस तरह करते हैं और यह अन्य सभी स्थानों का उपयोग करें:

#define NegativeNaN log(-1) 

आप बेहतर extended_exp() तरह exp() के आसपास कुछ बढ़ाया आवरण समारोह लिखना उन पर जोड़तोड़ किसी तरह का कार्य करना चाहते हैं और इसी तरह!

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