2009-10-13 14 views
6
float b = 1.0f; 
int i = (int)b; 
int& j = (int&)b; 

cout << i << endl; 
cout << j << end; 

का अर्थ है फिर i के उत्पादन 1 था, और 1065353216 के उत्पादन! यह मेरे लिए एक बड़ा आश्चर्य है! तो (int&) रूपांतरण का वास्तविक अर्थ क्या है?क्या (पूर्णांक और) सी में रूपांतरण ++

उत्तर

18

यह सी-स्टाइल कास्ट के साथ समस्या है। आपको क्या मिल रहा है यह देखने के लिए आपको बारीकी से देखना होगा। आपके मामले में "(int)" एक सामान्य स्थैतिक कलाकार था। मान को छंटनी के माध्यम से एक int में परिवर्तित किया जाता है। आपके मामले में "(int &)" एक पुन: परिभाषित कलाकार था। परिणाम एक अंतराल है जो बी के स्मृति स्थान को संदर्भित करता है लेकिन इसे int के रूप में माना जाता है। यह वास्तव में सख्त एलियासिंग नियमों का उल्लंघन है। इसलिए, अगर सभी कोड अनुकूलन चालू करने के बाद आपका कोड अब और काम नहीं करेगा तो surprized मत बनो।

समतुल्य कोड सी के साथ ++ शैली डाले:

float b = 1.0f; 
int i = static_cast<int>(b); 
int& j = reinterpret_cast<int&>(b); 
cout<<i<<endl; 
cout<<j<<end; 

डाले इन प्रकार पर अपने पसंदीदा सी ++ किताब की जाँच करें।

+0

हाँ, यह एक बहुत अच्छा जवाब है। लेकिन मुझे एक और सवाल मिलता है। एक त्रुटि क्यों, "त्रुटि: 'int &' टाइप करने के लिए 'float' प्रकार से अमान्य static_cast, तब हुआ जब मैंने static_cast का उपयोग int को फ़्लोट करने के लिए किया था और" फ्लोट बी = 1.0 एफ; int और j = static_cast b; "। मुझे अपनी पसंदीदा सी ++ पुस्तक, "सी ++ प्रोग्रामिंग भाषा" में static_cast की सीमाएं नहीं मिलीं। – toby

+3

यह सुरक्षा है जिसे आप सी ++ स्टाइल कास्ट का उपयोग करने से प्राप्त करते हैं। यदि संकलक एक static_cast संभावनाओं को स्वीकार करता है तो आप कुछ भी गलत नहीं कर रहे हैं। एकमात्र असुरक्षित चीजें जो एक स्थैतिक कलाकार आपको करने देती हैं, वह बेस */बेस और व्युत्पन्न */व्युत्पन्न और शून्य * से * * तक अनचेक रूपांतरण है जहां तक ​​मुझे याद है। यह मूल रूप से निहित रूपांतरणों को उलटा कर सकता है, अधिक नहीं - कॉन्स्ट रूपांतरणों की गणना नहीं कर रहा है। – sellibitze

+0

हाय, sellibitze, आपकी मदद के लिए धन्यवाद! मैं समझ गया! – toby

1

ऐसा लगता है कि आप (int) का उपयोग करके एक फ्लोट के लिए एक संदर्भ संदर्भ बनाने की कोशिश कर रहे हैं। यह काम नहीं करेगा क्योंकि फ्लोट int से भिन्न रूप से प्रदर्शित होते हैं। यह काम नहीं करेगा।

यदि फ्लोट और int का प्रतिनिधित्व समान है तो यह काम कर सकता है।

2
float b = 1.0f; 
... 
int& j = (int&)b; 

दूसरे रूपांतरण में, आप मेमोरी स्पेस को देख रहे हैं जिसमें बी है जैसे कि यह एक स्मृति स्थान था जिसमें एक int शामिल है। फ़्लोटिंग पॉइंट मान इस तरह से संग्रहीत होते हैं जो पूर्णांक के रूप में पूरी तरह से अलग होते हैं, इसलिए परिणाम वास्तव में अलग होते हैं ...

11

हेक्साडेसिमल 1065353216 0x3F800000 है। यदि आप इसे 32-बिट फ़्लोटिंग पॉइंट नंबर के रूप में समझते हैं तो आपको 1.0 मिलते हैं। आप बाइनरी में इसे बाहर लिखते हैं तो आप इस मिल:

 
3 F 8 0 0 0 0 0 
0011 1111 1000 0000 0000 0000 0000 0000 

या अलग ढंग से वर्गीकृत किया:

 
0 01111111 00000000000000000000000 
s eeeeeeee vvvvvvvvvvvvvvvvvvvvvvv 

पहली बिट (s) चिह्न सा है, अगले 8 बिट (e) प्रतिपादक हैं , और अंतिम 23 बिट्स (v) महत्वपूर्ण हैं। "एकल परिशुद्धता बाइनरी फ़्लोटिंग-पॉइंट एक्सपोनेंट ऑफसेट बाइनरी प्रस्तुति का उपयोग करके एन्कोड किया गया है, शून्य ऑफसेट 127 होने के साथ, IEEE 754 standard में एक्सपोनेंट पूर्वाग्रह के रूप में भी जाना जाता है।" इस व्याख्या में आप देखते हैं कि साइन 0 (सकारात्मक) है, एक्सपोनेंट 0 है (01111111 बी = 127, "शून्य ऑफसेट"), और महत्व 0 है। यह आपको +0 देता है जो 1.0 है।

किसी भी तरह, क्या हो रहा है कि आप एक फ्लोट (b) का संदर्भ ले रहे हैं और इसे एक संदर्भ संदर्भ (int&) के रूप में दोबारा परिभाषित कर रहे हैं। तो जब आप j के मान को पढ़ते हैं तो आपको b से बिट मिलते हैं। फ्लोट के रूप में व्याख्या की गई उन बिट्स का मतलब 1.0 है, लेकिन उन बिट्स के रूप में व्याख्या की गई है जो 10 बिट353216 है।

इसके लायक होने के लिए, मैंने कभी भी &(int&) जैसे कास्ट का उपयोग नहीं किया है। मैं इसे देखने या किसी भी सामान्य सी ++ कोड में इसका उपयोग करने की उम्मीद नहीं करता।

+0

अरे, यहां एक टाइपो है, (v) दो बार दोहराया जाता है, पहले (v) से (e) को ठीक करें। – legends2k

+0

मैंने जी ++ द्वारा उत्पन्न असेंबली कोड पढ़ा। यह कार्यक्रम में बिल्कुल हो रहा है। – toby

2

इस विशेष मामले में प्रश्न में रूपांतरण का कोई मतलब नहीं है।यह float ऑब्जेक्ट और int Lvalue द्वारा कब्जा कर लिया गया स्मृति पुन: परिभाषित करने का प्रयास है। यह सी/सी ++ में स्पष्ट रूप से अवैध है, जिसका अर्थ है कि यह अपरिभाषित व्यवहार पैदा करता है। अपरिभाषित व्यवहार - यही एकमात्र अर्थ है जो इस मामले में है।

1

आप क्या करने जा रहे थे? एक ही बात:

float b = 1.0f; 
int i = (int) b; 
int* j = (int*)b;//here we treat b as a pointer to an integer 
cout<<i<<endl; 
cout<<(*j)<<endl; 

ठीक करने के लिए कैसे:

float b = 1.0f; 
int i = (int) b; 
int castedB = (int)b;//static_cast<int>(b); 
int& j = castedB; 
cout<<i<<endl; 
cout<<j<<endl; 
संबंधित मुद्दे