2011-10-15 16 views
13

यह देखने के लिए मेरे लिए आश्चर्य की बात है कि जब मूल्य परिवर्तित किया जा सकता है, तब भी रूपांतरण करने के लिए एक int हमेशा चेतावनी देता है। ऐसा क्यों है?इंट फ्लोट रूपांतरण एक चेतावनी पैदा करता है?

int i = 0; 
float f = 0; // warning here 

// I thought this was an implicit conversion, 
// meaning it is convertible with no warnings. 
f = i;  // another warning here 

चेतावनी है:

warning C4244: '=' : conversion from 'int' to 'float', possible loss of data 
+1

फ़्लोट प्रकार के लिए MAX INT मान असाइन करें और परिणाम देखें। –

+3

फ्लोट एफ = 0.0 एफ; // 0 पूर्णांक है। –

+0

यह 'f = MAXINT;' और 'f = INT_MAX;' – user103214

उत्तर

4

मैं एक ऐसी ही प्रश्न का यहां उत्तर:

Why does GCC warn against this implicit conversion?

कारण यह है कि जब यह एक में casted है पूर्ण होना एक int की जरूरत है float क्योंकि float में इस सीए में int की सभी सटीकता शामिल नहीं हो सकती से।

आपके मामले में, float में केवल 24 बिट सटीक हैं। जबकि int में 32 बिट सटीक हैं, इसलिए, इस सटीकता से कुछ सटीकता हानि होती है, इसलिए चेतावनी।

+0

वहां (और हैं) कार्यान्वयन हो सकते हैं जहां' फ्लोट 'जानकारी के नुकसान के बिना' int' के सभी मानों को पकड़ सकता है - उदाहरण के लिए यदि 'int' और 'फ्लोट' क्रमश: 16 और 32 बिट्स हैं, या 32 और 64 बिट्स हैं। लेकिन संकलक जारी करने का निर्णय लेते समय संकलक विशेष कार्यान्वयन के बारे में जानकारी का उपयोग करने के लिए नि: शुल्क हैं। –

+0

मुझे एहसास है कि, इसलिए मैंने अपने जवाब में "इस मामले में" डाला है क्योंकि इसे सार्वभौमिक रूप से सत्य नहीं माना जाता है। – Mysticial

10

यह आपके int प्रकार में कितने बिट्स पर निर्भर करता है इस पर निर्भर करता है। आईईईई 754 एकल परिशुद्धता एक फ्लोट 32-बिट मान है, लेकिन उनमें से कुछ बिट्स एक्सपोनेंट को सौंपा गया है, जिसका अर्थ है कि सभी परिशुद्धता के लिए उपलब्ध नहीं हैं।

यदि आपके int प्रकार आपके float से अधिक सटीक है, तो आपको उच्च अंत में परिशुद्धता का नुकसान हो सकता है।

दूसरे शब्दों में, यह INT_MAX और INT_MAX - 1 के बीच अंतर करने में सक्षम नहीं हो सकता है।

उस मामले में समाधान एक व्यापक फ्लोटिंग पॉइंट प्रकार (double) का उपयोग करने हालांकि, तकनीकी रूप से, आप एक कार्यान्वयन एक 256-बिट int प्रकार जिस स्थिति में आप एक और तरीका खोजने के लिए :-) होगा है कि मिल सकता है है

This answer इस बारे में एक संक्षिप्त अवलोकन है कि फ्लोटिंग पॉइंट प्रारूप कैसे काम करते हैं, इस तथ्य के साथ कि 32 बिट्स में से केवल 23 मंटिसा की परिशुद्धता के लिए उपलब्ध हैं।

3

बस मस्ती के लिए, यह कोशिश करते हैं और देखते हैं कि क्या उत्पादन होता है (संकेत, तुम सब करने के लिए संख्या उम्मीद होती ही हो, तुम नहीं चाहेगा?):

int i1(INT_MAX), i2; 

float f(i1); 

i2 = f; 

std::cout << i1 << ' ' << f << ' ' << i2 << '\n'; 

खैर, जवाब मैं कर रहे हैं:

2147483647 2.14748e+009 -2147483648 

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

जिस तरह से मैं पूरी तरह से सुनिश्चित नहीं हूं कि उपर्युक्त परिणाम क्यों होता है। शायद कोई और समझा सकता है!

+0

यह मुझे दो चेतावनियां देता है, एक फ्लोट शुरू करने पर और एक फ्लोट में कनवर्ट करने पर। – user103214

+0

@ user974191: यह आपके मूल प्रश्न से स्पष्ट नहीं था। मैंने इसे उस जानकारी को प्रतिबिंबित करने के लिए अपडेट किया है (हालांकि मुझे आश्चर्य है कि यह 'फ्लोट एफ = 0;' के बारे में चेतावनी दी गई है। कृपया मेरे संपादन की समीक्षा करें। –

1

// मुझे लगा कि यह निहित था रूपांतरण यह साथ covertible कोई चेतावनी है इसका मतलब है?

नहीं, इसका मतलब यह नहीं है। इसका मतलब यह है कि आप बिना किसी स्पष्ट रूपांतरण (यानी, एक कास्ट) के किसी अन्य प्रकार के किसी ऑब्जेक्ट को एक प्रकार का मान असाइन कर सकते हैं, और मान को पूरी तरह से परिवर्तित किया जाएगा।

और इस मामले में, एक चेतावनी उचित हो सकती है। int और float दोनों 32 बिट कर रहे हैं (जो ठेठ लेकिन सार्वभौमिक नहीं है), तो प्रकार int के सभी मानों रेंज float की भीतर कर रहे हैं, लेकिन वह वास्तव में प्रकार float में नहीं दर्शाया जा सकता प्रकार int के कई मूल्यों देखते हैं।

भाषा मानक को किसी भी अनुवाद इकाई (स्रोत फ़ाइल) के लिए कम से कम एक डायग्नोस्टिक संदेश की आवश्यकता होती है जो वाक्यविन्यास नियम या बाधा का उल्लंघन करती है। लेकिन कंपाइलर्स अतिरिक्त डायग्नोस्टिक को जारी करने के लिए स्वतंत्र हैं।

+0

अतिरिक्त कंपाइलर डायग्नोस्टिक्स पर एक महत्वपूर्ण प्रतिबंध है - संकलक मानक-अनुपालन कार्यक्रम के संकलन को असंभव प्रस्तुत करने के लिए इतने सारे डायग्नोस्टिक्स जारी नहीं कर सकता है। कुछ कंपाइलर्स रहे हैं (पता नहीं है कि अभी भी हैं) जो मर जाएंगे यदि एक लाइन ने बहुत सी चेतावनियां उत्पन्न की हैं। जबकि एक पंक्ति के लिए हजारों चेतावनियां उत्पन्न करना असामान्य होगा, मानकों के लिए ऐसा करने के लिए एक मानक-कंपिलेंट प्रोग्राम के लिए संभव होगा। – supercat

+0

@supercat: यह केवल डायग्नोस्टिक्स नहीं, संकलक करता है, जो कुछ भी करता है, के बराबर लागू होता है। आप जो वर्णन कर रहे हैं वह केवल एक कंपाइलर बग है; आमतौर पर ग्यारह गजियन चेतावनियां जारी करने से संकलक को क्रैश नहीं होता है। और मानक क्षमता सीमा के कारण मानक विफल होने के लिए संकलक अनुमति देता है; इसे केवल एक * एकल * प्रोग्राम का अनुवाद और निष्पादन करने की आवश्यकता होती है जो सभी निर्दिष्ट सीमाओं तक पहुंच जाती है (सी 99 5.2.4.1)। –

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