2011-08-08 6 views
9

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

मैं वर्तमान में निम्नलिखित का प्रयास कर रहा हूं, क्या यह सही है?

if (std::abs(x) < DBL_MIN) { 
    log_debug("detected small num, %Le, %Le", x, y); 
} 

दूसरा, गणित की प्रकृति प्रकृति में त्रिकोणमितीय, परिवर्तनों किस तरह मैं गणितीय त्रुटियों से बचने के लिए कर सकते हैं (उर्फ आदि रेडियन/डिग्री रूपांतरण का एक बहुत और sin/cos/tan कॉल, का उपयोग) है ?

स्पष्ट रूप से गुणाओं के लिए मैं log transform का उपयोग कर सकता हूं - और क्या?

+0

क्या हम गणित के उदाहरण को देख सकते हैं, ताकि हम कुछ सुरुचिपूर्ण तैयार कर सकें? मेरे दिमाग में जो कुछ है वह 'cos x - 1' जैसी चीजें हैं जब आप शून्य के आसपास धीरे-धीरे परिणाम बदल सकते हैं, और सावधानीपूर्वक सहिष्णुता का चयन करना होगा। –

+1

परिवर्तनों के लिए अंडरफ्लो से बचने के लिए, सबसे प्रत्यक्ष एक टेलर को आपके अभिव्यक्तियों का विस्तार करना है और छोटे तर्कों के लिए क्या आता है इसका उपयोग करना है। उदाहरण के लिए, '1-cos (x)' के बजाय 'x * x/2' का उपयोग 'x' के लिए कुछ कटऑफ से छोटा है। –

उत्तर

2

तो x एक डबल, फिर एक इस दृष्टिकोण के साथ समस्या यह है कि आप x के बीच भेद नहीं कर सकते हैं वैध तरीके से शून्य जा रहा है, और x एक सकारात्मक मूल्य DBL_MIN की तुलना में छोटे किया जा रहा है। तो यह काम करेगा अगर आपको पता है कि x वैध रूप से शून्य नहीं हो सकता है, और आप देखना चाहते हैं कि अंडरफ्लो कब होता है।

आप SIGFPE सिग्नल को पकड़ने का भी प्रयास कर सकते हैं, जो किसी भी समय पॉसिक्स-अनुपालन प्रणाली पर आग लग जाएगा जब फ्लोटिंग-पॉइंट अंडरफ्लो सहित गणित त्रुटि हो। देखें: http://en.wikipedia.org/wiki/SIGFPE

संपादित: स्पष्ट है कि, DBL_MIN सबसे बड़ा नकारात्मक मूल्य है कि एक डबल धारण कर सकते हैं नहीं है, यह छोटी से छोटी सकारात्मक normalized मूल्य कि एक डबल पकड़ कर सकते हैं। तो आपका दृष्टिकोण तब तक ठीक है जब तक कि मूल्य शून्य न हो।

एक और उपयोगी स्थिरांक DBL_EPSILON है जो कि सबसे छोटा डबल मान है जिसे 1.0 को वापस बिना 1.0 में जोड़ा जा सकता है। ध्यान दें कि यह DBL_MIN से बहुत अधिक मूल्य है। लेकिन यह आप के लिए उपयोगी हो सकती है, क्योंकि त्रिकोणमितीय कार्यों कि बजाय की ओर 0.

2

प्रवृत्त आप सी ++ का उपयोग कर रहे के बाद से 1 की ओर जाते हैं हो सकता है कर रहे हैं, सबसे मुहावरेदार हैडर <limits> से std::numeric_limits उपयोग करने के लिए है।

उदाहरण के लिए:

template <typename T> 
bool is_close_to_zero(T x) 
{ 
    return std::abs(x) < std::numeric_limits<T>::epsilon(); 
} 

वास्तविक सहिष्णुता भारी प्रयोग की जाने वाली आपकी समस्या पर निर्भर करता है। कृपया एक ठोस उपयोग मामले के साथ अपना प्रश्न पूरा करें ताकि मैं अपना उत्तर बढ़ा सकूं।

std::numeric_limits<T>::min() और std::numeric_limits<T>::denorm_min() भी उपयोगी हो सकता है। पहला(FLT/DBL/LDBL_MIN के बराबर <cfloat> से) का सबसे छोटा सकारात्मक गैर-डिमॉर्मलाइज्ड मान है, दूसरा दूसरा T (<cfloat> समकक्ष) का सबसे छोटा सकारात्मक मान है।

[आप को पढ़ने के लिए this document उपयोगी लग सकती है अगर आप चल बिन्दु संख्या प्रतिनिधित्व के साथ आराम से नहीं कर रहे हैं।]

+0

शायद बाद में, मुझे पता चला कि eqns का कौन सा हिस्सा समस्या पैदा कर रहा है। सी ++ tidbit के लिए धन्यवाद! – Petriborg

+0

'डीबीएल_MIN' सबसे छोटा सकारात्मक ** सामान्यीकृत **' डबल' मान है, इसलिए यह 'min()' और 'denorm_min()' के अनुरूप नहीं होगा। –

+0

@ डैनियल फिशर: वास्तव में, धन्यवाद। सही किया। –

0

पहले if जांच वास्तव में ही सच्चा होगा जब आपके मूल्य शून्य है।

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

+0

'डीबीएल_MIN' सबसे छोटा सकारात्मक ** सामान्यीकृत ** डबल मान है, छोटे सकारात्मक 'डबल' हैं। –

5

व्यापक धारणा के विपरीत, DBL_MIN नहीं छोटी से छोटी सकारात्मक double मूल्य लेकिन छोटी से छोटी सकारात्मक सामान्यीकृतdouble मूल्य है। आम तौर पर - 64-बिट यानी 754 doubles के लिए - यह 2 -1022 है, जबकि सबसे छोटा सकारात्मक double मान 2 -1074 है। इसलिए

मैं वर्तमान में निम्नलिखित का प्रयास कर रहा हूं, क्या यह सही है?

if (std::abs(x) < DBL_MIN) { 
    log_debug("detected small num, %Le, %Le", x, y); 
} 

का सकारात्मक जवाब हो सकता है। स्थिति जांचती है कि xdenormalized (जिसे सबनोर्मल भी कहा जाता है) संख्या या ± 0.0 है। आपकी विशिष्ट स्थिति के बारे में और जानने के बिना, मैं यह नहीं बता सकता कि वह परीक्षण उचित है या नहीं। Denormalized संख्या गणना के वैध परिणाम या गोल परिणाम के परिणाम हो सकता है जहां सही परिणाम 0 होगा। यह भी संभव है कि गोलाकार DBL_MIN से कहीं अधिक तीव्रता की संख्या पैदा करता है जब गणितीय सही परिणाम 0 होगा, तो एक बहुत बड़ी दहलीज हो सकती है समझदार बनना।

+0

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

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