2009-06-24 11 views
13

क्या यह गैर-गणितीय कारणों के लिए अपरिभाषित मानों के लिए IEEE754 फ़्लोटिंग पॉइंट NaN (संख्या-संख्या) का उपयोग करना अच्छा विचार है?क्या यह निर्धारित करने के लिए IEEE754 फ़्लोटिंग पॉइंट NaN का उपयोग करना अच्छा विचार है?

हमारे मामले में वे अभी तक सेट नहीं हैं क्योंकि मान किसी अन्य डिवाइस से प्राप्त नहीं हुए हैं। संदर्भ IEC1131 REAL32 मानों का उपयोग कर एक एम्बेडेड सिस्टम है। संपादित करें: प्रोग्रामिंग भाषा सी है, इसलिए हम सबसे अधिक संभावना एनएएन और इस्नाफ (एक्स) का उपयोग करेंगे, जो सी 99 से हैं। हालांकि हमें इन्हें ओएस संगतता परत में लाने के लिए कुछ अतिरिक्त योगदान की आवश्यकता हो सकती है।

प्रोग्रामिंग भाषाओं में डिफ़ॉल्ट सकारात्मक शून्य के साथ फ़्लोटिंग पॉइंट चर शुरू करने के लिए प्रतीत होता है, जिसका आंतरिक प्रतिनिधित्व सभी शून्य है। यह हमारे लिए उपयोग योग्य नहीं है, क्योंकि 0 मान्य मानों की सीमा में है।

यह नाएन का उपयोग करने के लिए एक स्वच्छ समाधान की तरह लगता है, लेकिन हो सकता है कि यह अधिक मूल्यवान है और इसके लायक है और हमें कुछ और मूल्य चुनना चाहिए?

+0

मुझे सी नहीं पता, लेकिन .NET 1.1 में पहले शून्य प्रकारों से बाहर निकलने से पहले, बहुत से लोग न्यूनतम मूल्य (int.MinValue) जैसी चीजों का उपयोग करते थे। इसके साथ समस्या यह है कि आपको हर जगह इसे कारक बनाना होगा और यह सुनिश्चित करना होगा कि आप MinValue का कभी भी उपयोग न करें। शायद सी के लिए उन पंक्तियों के साथ कुछ मौजूद है? – RichardOD

+1

मैंने एक समान (लेकिन समान नहीं) प्रश्न पूछा, शायद उत्तर भी आपकी मदद कर सकते हैं। http://stackoverflow.com/questions/787828/nan-as-a-special-argument – quinmars

उत्तर

10

बस इस प्रश्न को देखा।

यह एनईएन के उपयोगों में से एक है कि आईईईई 754 समिति को ध्यान में रखा गया है (मैं एक समिति सदस्य था)। अंकगणित में NaNs के प्रचार नियम यह बहुत आकर्षक बनाते हैं, क्योंकि यदि आपके पास गणना के लंबे अनुक्रम से परिणाम होता है जिसमें कुछ प्रारंभिक डेटा शामिल होते हैं, तो आप एक वैध परिणाम के परिणाम को गलती नहीं करेंगे। यह आपके गणना के माध्यम से पीछे की ओर ट्रेसिंग भी कर सकता है यह पता लगाने के लिए कि आप प्रारंभिक डेटा का उपयोग अधिक सरल कहां कर रहे हैं।

यह कहा गया है कि 754 समिति के नियंत्रण के बाहर कुछ नुकसान हैं: जैसा कि अन्य ने नोट किया है, सभी हार्डवेयर गति पर NaN मानों का समर्थन नहीं करते हैं, जिसके परिणामस्वरूप प्रदर्शन के खतरे हो सकते हैं। सौभाग्य से, कोई प्रदर्शन-महत्वपूर्ण सेटिंग में प्रारंभिक डेटा पर अक्सर कई संचालन नहीं करता है।

+0

स्वीकृत क्योंकि हमने इस मामले में अपरिभाषित के लिए NaN का उपयोग किया था, हालांकि यह अपेक्षा से अधिक परेशानी का कारण बन गया। यह ज्यादातर इसलिए था क्योंकि हमारे उपकरण और प्रणालियों में NaN समर्थन गुम या छोटी थी और हमें इसके आसपास काम करना पड़ा। – starblue

3

मैंने इसी तरह की स्थितियों में नाएन का उपयोग किया है क्योंकि सामान्य कारण: सामान्य डिफ़ॉल्ट प्रारंभिक मान 0 भी वैध मान है। NaNs अभी तक ठीक काम करते हैं।

यह एक अच्छा सवाल है, वैसे, डिफ़ॉल्ट प्रारंभिक मान आमतौर पर क्यों होता है (उदाहरण के लिए, जावा आदिम प्रकारों में) 0 और NaN नहीं। क्या यह 42 या जो भी हो सकता है? मुझे आश्चर्य है कि शून्य का तर्क क्या है।

+1

मुझे लगता है कि 0 का उपयोग करने के लिए तर्क यह है कि स्मृति के प्रकार को शून्य बाइट्स के साथ शुरू किया गया है, उदाहरण के लिए सी के बीएसएस सेगमेंट में – starblue

+0

हाँ, शायद यह ऐसा कुछ है।लेकिन अब जब भाषा/कंपाइलर डिजाइनरों ने स्मृति को आरंभ करने का प्रयास किया है, तो क्या यह किसी भी मनमाना मूल्य (शून्य के अलावा) शुरू करना लगभग आसान नहीं होगा? ज़ीरोस दूसरों के बीच बस बिट्स हैं :-) –

+2

@ पागल-जे: आप एक ही बिट पैटर्न के साथ सभी मेमोरी को init करना चाहते हैं। तो यह 42 नहीं हो सकता है, क्योंकि तब आप आमतौर पर दो आसन्न शॉर्ट्स के लिए कुछ अलग करना चाहते हैं जो आप int के लिए करते हैं। यह 0 और -1 छोड़ देता है। लेकिन 0xffffffff एक फ्लोट के रूप में -1 नहीं है, इसलिए आपके पास एक असंगतता होगी। इसमें बहुत कुछ नहीं है, लेकिन मुझे लगता है कि 0 शायद सबसे अच्छा है। इसके अलावा कुछ हार्डवेयर एक ही समय में भौतिक स्मृति के पूरे ब्लॉक कुशलतापूर्वक 0 कर सकते हैं, जो इसके लायक है। –

0

यदि आपका बुनियादी जरूरत एक चल बिन्दु मूल्य जो किसी भी संख्या जो संभवतः डिवाइस, और डिवाइस यह NaN वापस कभी नहीं होगा की गारंटी देता है, तो से प्राप्त किया जा सकता था का प्रतिनिधित्व नहीं करता है, तो यह करने के लिए उचित लगता है मुझे।

बस है कि अपने परिवेश के आधार पर, तो आप शायद Nans का पता लगाने के एक विशेष तरीके की जरूरत है याद (बस if (x == float.NaN) का उपयोग नहीं करते या अपने बराबर है जो कुछ भी।)

+0

इस उत्तर पर विश्वास नहीं है। सभी जॉन स्कीट को चर के बारे में सोचना है और यह खुद को परिभाषित करेगा। –

+0

मान को वैरिएबल नाम की स्कीट चीजों से पहले परिभाषित किया गया है, है ना? – glasnt

4

Nans एक 'नो मूल्य' के लिए एक उचित विकल्प हैं sentential (डी प्रोग्रामिंग भाषा, उदाहरण के लिए अप्रारंभीकृत मूल्यों के लिए उन्हें का उपयोग करता है), लेकिन क्योंकि किसी भी उन्हें शामिल तुलना गलत हो जाएगा, तो आपको कुछ आश्चर्य प्राप्त कर सकते हैं:

  • if (result == DEFAULT_VALUE), अगर DEFAULT_VALUE अपेक्षा के अनुरूप काम नहीं करेगा जॉन ने उल्लेख किया है, नाएन है।

  • यदि आप सावधान नहीं हैं तो वे रेंज जांच के साथ समस्याएं भी पैदा कर सकते हैं। समारोह पर विचार करें:

 
bool isOutsideRange(double x, double minValue, double maxValue) 
{ 
    return x < minValue || x > maxValue; 
} 

यदि x NaN है, इस समारोह को गलत ढंग से रिपोर्ट करेंगे कि एक्स MINVALUE और MAXVALUE के बीच है।

यदि आप सिर्फ उपयोगकर्ताओं के खिलाफ परीक्षण करने के लिए जादू मूल्य चाहते हैं, तो मैं नाएन के बजाय सकारात्मक या नकारात्मक अनंतता की सिफारिश करता हूं, क्योंकि यह उसी जाल के साथ नहीं आता है। जब आप इसे अपनी संपत्ति के लिए चाहते हैं तो NaN का उपयोग करें कि NaN पर किसी भी ऑपरेशन को NaN में परिणाम: यह आसान है जब आप मूल्य की जांच करने वाले कॉलर्स पर भरोसा नहीं करना चाहते हैं, उदाहरण के लिए।

[संपादित करें: मैंने शुरुआत में "उनसे तुलना करने वाली किसी भी तुलना को सत्य" कहा, जो मेरा मतलब नहीं था, और गलत है, वे सभी झूठे हैं, नाएन के अलावा!= NaN, जो सच है]

+0

कौन सी भाषा इन तुलना नियमों का उपयोग करती है? शायद डी करता है। लेकिन कम से कम सी और सी ++ इस तरह NaN के साथ काम नहीं करते हैं। सभी ऑर्डरिंग तुलना गलत होगी। x == NaN NaN सहित किसी भी x के लिए गलत है। –

+1

नहीं, आपका फ़ंक्शन केवल रिपोर्ट करता है कि यह सीमा से बाहर नहीं है। यह न तो अंदर और न ही बाहर है, जो वास्तव में फ़्लोटिंग पॉइंट नंबरों का उपयोग करके उन लोगों को भ्रमित कर सकता है। – starblue

+0

@ इगोर: हम यहां वही बात कह रहे हैं। यदि एक्स नैन है तो isOutsideRange झूठी वापसी करेगा, जिसका अर्थ यह है कि यह सीमा के अंदर है, जो यह नहीं है। – jskinner

1

मेरी भावनाएं हैं कि यह थोड़ा हैकी है, लेकिन कम से कम हर दूसरे नंबर जो आप इस NaN मान के साथ संचालन करते हैं, परिणामस्वरूप नाइन देता है - जब आप कम से कम एक बग रिपोर्ट में NaN देखते हैं, कम से कम आप जानते हैं कि आप किस प्रकार की गलती कर रहे हैं।

2

नाएन के साथ सावधान रहें ... यदि आप सावधान नहीं हैं तो वे जंगल की आग की तरह फैल सकते हैं।

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

डी डिफ़ॉल्ट रूप से फ्लोट NaN देने के लिए तर्क के रूप में इसका उपयोग करता है। (जो मुझे यकीन नहीं है कि मैं इसके साथ सहमत हूं।)

+9

एर ... क्या यह सिर्फ एनएनएस का मुद्दा नहीं है कि वे प्रचार करेंगे? नतीजे के परिणामस्वरूप यह बेहतर होता है, जो इंगित करता है कि एक निर्दोष दिखने वाला लेकिन पूरी तरह से गलत संख्या (जो शून्य-प्रारंभिक संख्याओं के आकस्मिक उपयोग के परिणामस्वरूप) के मुकाबले कुछ गड़बड़ है। –

+1

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

+0

यदि आप कभी भी जानते हैं कि NaNs हर जगह हैं, तो यह वास्तव में यह जानने में आपकी सहायता नहीं करता कि वे कहां से आ रहे हैं। – corsiKa

3

मुझे लगता है कि यह सामान्य रूप से एक बुरा विचार है। ध्यान में रखना एक बात यह है कि अधिकांश सीपीयू नैन को धीमे "सामान्य" फ्लोट का इलाज करते हैं। और यह गारंटी देना मुश्किल है कि आपके पास सामान्य सेटिंग्स में नैन कभी नहीं होगा। संख्यात्मक कंप्यूटिंग में मेरा अनुभव यह है कि यह अक्सर इसके लायक से अधिक परेशानी लाता है।

सही समाधान फ्लोट में "मूल्य की अनुपस्थिति" एन्कोडिंग से बचने के लिए है, लेकिन इसे किसी अन्य तरीके से सिग्नल करने के लिए है। यह हमेशा आपके व्यावहारिक नहीं है, हालांकि, आपके कोडबेस के आधार पर।

0

यह मेरे लिए नैन के लिए एक अच्छा उपयोग की तरह लगता है। इच्छा है कि मैंने इसके बारे में सोचा था ...

निश्चित रूप से, वे एक वायरस की तरह प्रचार करना चाहते हैं, यही बात है।

मुझे लगता है कि मैं infinities में से एक के बजाय नैन का उपयोग करेंगे। सिग्नलिंग नैन का उपयोग करना अच्छा हो सकता है और इसे पहले उपयोग पर एक ईवेंट का कारण बन सकता है, लेकिन तब तक बहुत देर हो चुकी है, इसे पहले उपयोग पर शांत होना चाहिए।

0

डिफ़ॉल्ट मान के रूप में NaN का उपयोग करना उचित है।

ध्यान दें कि कुछ अभिव्यक्तियां, जैसे कि (0.0/0.0), NaN वापस आती हैं।

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