2012-04-28 14 views
10

अनदेखी कारण है कि मैं ऐसा करना चाहते हैं, 754 आईईईई fp मानक का पालन करने के लिए व्यवहार को परिभाषित नहीं करता तैरता:समस्याएं कास्टिंग नेन int करने के लिए

float h = NAN; 
printf("%x %d\n", (int)h, (int)h); 

Gives: 80000000 -2147483648 

असल में, नान किस मूल्य मैं दे की परवाह किए बिना , यह 80000000 (हेक्स) या -2147483648 (डीसी) आउटपुट करता है। क्या इसका कोई कारण है और/या यह सही व्यवहार है? यदि हां, तो कैसे आते हैं? तो मूल रूप से How can I manually set the bit value of a float that equates to NaN?

, कर रहे हैं कि ऐसी स्थितियां NaN का पेलोड कलाकारों के उत्पादन को प्रभावित करता है:

तरह से मैं यह NaN के विभिन्न मान रहा हूं यहाँ हैं?

धन्यवाद!

+4

+1 क्योंकि हैकिंग बेहतर समझने की ओर जाता है –

+0

आपको इसके लिए क्या चाहिए? –

उत्तर

10

एक पूर्णांक के लिए एक फ़्लोटिंग पॉइंट नंबर की एक कलाकार का परिणाम पूर्णांक चर (tr 1 छिड़काव के लिए) की सीमा में नहीं मानों के लिए अपरिभाषित है।

NaN सीमा से बाहर है, इसलिए परिणाम अपरिभाषित है।

वास्तव में, मानक केवल परिमित के पूर्णांक प्रकारों के फ़्लोटिंग पॉइंट प्रकारों के रूपांतरण का उल्लेख करता है।

+1

इस तथ्य को देखते हुए कि व्यवहार अपरिभाषित है, नतीजा यह है कि मुझे इस अपरिभाषित व्यवहार के लिए आम मिला है? यानी क्या किसी को सिस्टम के बारे में पता है क्या मुझे इससे अलग व्यवहार मिलेगा? 754 spec का कहना है कि NaN संचालन का व्यवहार यह है कि पेलोड के माध्यम से किया जाना चाहिए। – Chris

+0

मुझे एक कार्यान्वयन से अवगत नहीं है जो अन्यथा करता है, लेकिन मैं कुछ जीसीसी से परे कुछ भी परिचित नहीं हूं। जीसीसी सभी आउट-ऑफ-रेंज रूपांतरणों के लिए 'intT_MIN' का उत्पादन करता है, जहां तक ​​मुझे पता है (लेकिन यह भी बहुत छोटा है)। –

+0

मुझे यकीन है कि आपका मतलब है * x86 * पर gcc *। परिणाम मानने का कोई कारण नहीं है कि परिणाम हर जगह समान होना चाहिए; यह संभवतः एफपीयू के व्यवहार का एक आर्टिफैक्ट है। –

1

सबसे पहले, एनएएन सब कुछ आईईईई मानक के अनुसार फ्लोट नंबर नहीं माना जाता है। तो यह कई चीजें हो सकती है। कंपाइलर में मैं एनएएन और -एनएएन के साथ काम करता हूं, इसलिए यह केवल एक मान नहीं है।

दूसरा, प्रत्येक कंपाइलर के पास isnan इस मामले के परीक्षण के लिए कार्यों का सेट है, इसलिए प्रोग्रामर को खुद बिट्स से निपटने की ज़रूरत नहीं है। संक्षेप में, मुझे नहीं लगता कि मूल्य पर peeking कोई फर्क पड़ता है। आप अपने आईईईई निर्माण, जैसे साइन, मंटिसा और एक्सपोनेंट को देखने के लिए मूल्य देख सकते हैं, लेकिन फिर से, प्रत्येक कंपाइलर इसके कार्यों को पूरा करने के लिए अपने कार्यों (या बेहतर कहने, लाइब्रेरी) देता है।

मेरे पास आपके परीक्षण के बारे में और कुछ कहना है, हालांकि।

float h = NAN; 
printf("%x %d\n", (int)h, (int)h); 

कास्टिंग आपने इसे एक int में बदलने के लिए फ्लोट को ट्राउट किया था। आप पूर्णांक नाव द्वारा प्रतिनिधित्व प्राप्त करना चाहते हैं, कर

printf("%x %d\n", *(int *)&h, *(int *)&h); 

पीछा कर रहा है यही कारण है कि, आप, नाव के पते ले तो एक सूचक int करने के लिए ही कहते हैं, और अंततः पूर्णांक मान ले । इस तरह थोड़ा प्रतिनिधित्व संरक्षित है।

7

इस व्यवहार का एक कारण है, लेकिन ऐसा कुछ नहीं है जिसे आपको आम तौर पर भरोसा करना चाहिए।

जैसा कि आप ध्यान देते हैं, आईईईई -754 निर्दिष्ट नहीं करता है कि जब आप फ्लोटिंग-पॉइंट NaN को एक पूर्णांक में परिवर्तित करते हैं, सिवाय इसके कि इसे एक अमान्य ऑपरेशन अपवाद उठाना चाहिए, जो आपका कंपाइलर शायद अनदेखा करता है। सी कंपाइलर का कहना है कि व्यवहार अपरिभाषित है, जिसका मतलब है कि न केवल आपको पता है कि आपको कौन सा पूर्णांक परिणाम मिलेगा, आपको नहीं पता कि आपका प्रोग्राम बिल्कुल क्या करेगा; मानक प्रोग्राम को निरस्त करने या पागल परिणाम पाने या कुछ भी करने की अनुमति देता है। आपने शायद इस प्रोग्राम को इंटेल प्रोसेसर पर निष्पादित किया है, और आपके कंपाइलर ने अंतर्निहित निर्देशों में से किसी एक का उपयोग करके रूपांतरण किया है। इंटेल निर्देश व्यवहार को बहुत सावधानीपूर्वक निर्दिष्ट करता है, और फ्लोटिंग-पॉइंट नाइन को 32-बिट पूर्णांक में परिवर्तित करने का व्यवहार 0x80000000 वापस करना है, चाहे नाएन के पेलोड के बावजूद, जो आपने देखा है।

क्योंकि इंटेल निर्देश व्यवहार को निर्दिष्ट करता है, यदि आप निर्देशों का उपयोग करते हैं तो आप उस पर भरोसा कर सकते हैं। हालांकि, चूंकि संकलक आपको ऐसी गारंटी प्रदान नहीं करता है, इसलिए आप इस निर्देश पर भरोसा नहीं कर सकते हैं।

+1

यह सच हो सकता है कि इंटेल प्रोसेसर एनएएन को 32-बिट int में '0x80000000' के रूप में परिवर्तित करते हैं, लेकिन यह आपकी मदद नहीं करेगा यदि आपका एनएएन आपके कंपाइलर द्वारा निर्धारित स्थिर मूल्य है। ऐसे मामलों में आप INT_MIN के अलावा अन्य मान देख सकते हैं, क्योंकि रूपांतरण रनटाइम के बजाए संकलन समय पर किया जाता है, इसलिए इंटेल का x86 अर्थशास्त्र कभी भी खेल नहीं आता है। उदाहरण के लिए, जब जीसीसी संकलन समय पर एनएएन को int में परिवर्तित करता है, तो यह 0 देता है। –

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