2011-08-22 13 views
10

संभव डुप्लिकेट:
signed to unsigned conversion in C - is it always safe?क्या होता है जब मैं एक हस्ताक्षरित int को ऋणात्मक मान निर्दिष्ट करता हूं?

मान लीजिए कि मैं प्रकार अहस्ताक्षरित int की एक चर घोषित करते हैं: unsigned int x = -1;

अब -1 दो के पूरक में (यह मानते हुए 32 बिट मशीन) 0xFFFFFFFF है । अब जब मैंने x को यह मान असाइन किया था, तो क्या मान 0x7FFFFFFF को x को असाइन किया गया था?

यदि ऐसा था, तो printf ("% d", x); 0x7FFFFFFF के दशमलव समकक्ष मुद्रित किया होगा, है ना? लेकिन, स्पष्ट रूप से यह नहीं हो रहा है, क्योंकि मुद्रित मूल्य -1 है। मुझे यहां क्या समझ नहीं आ रहा है?

संपादित करें: मुझे पता है कि हम हस्ताक्षर किए गए मान मुद्रित करने के लिए% u प्रारूप विनिर्देश का उपयोग कर सकते हैं। लेकिन यह उपरोक्त प्रश्न का उत्तर देने में मदद नहीं करता है।

+2

'0x7FFFFFFF कहां से आया था? –

+0

@Evan: एमएसबी फ़्लिपिंग। बस एक अनुमान है, क्योंकि मुझे नहीं पता कि रूपांतरण वास्तव में कैसे होता है – n0nChun

+0

सी 99 मानक के खंड 6.3.1.3 को आपके प्रश्न का उत्तर देना चाहिए। लेकिन इससे आपके प्रश्न का थोड़ा बेहतर जवाब देना चाहिए http://stackoverflow.com/questions/50605/signed-to-unsigned-conversion-in-c-is-it-always-safe – Joe

उत्तर

14

"%d" प्रारूप (हस्ताक्षरित) int मानों के लिए है। यदि आप इसे बिना हस्ताक्षरित मान के साथ उपयोग करते हैं, तो यह वास्तविक मान के अलावा कुछ और प्रिंट कर सकता है। हेक्साडेसिमल में देखने के लिए वास्तविक मान, या %x देखने के लिए "%u" का उपयोग करें।

घोषणा

unsigned int x = -1; 

अभिव्यक्ति -1 में प्रकार int की है, और उसका मान -1। प्रारंभकर्ता इस मान को int से unsigned int में परिवर्तित करता है। हस्ताक्षरित-हस्ताक्षरित रूपांतरण के नियमों का कहना है कि मान कम हो गया है मॉड्यूल UINT_MAX + 1, इसलिए -1UINT_MAX में परिवर्तित हो जाएगा (जो 0xffffffff या 4294967295 है यदि unsigned int 32 बिट्स है)।

आप बस एक हस्ताक्षरित प्रकार की किसी वस्तु को ऋणात्मक मान निर्दिष्ट नहीं कर सकते हैं। इस तरह के किसी भी मूल्य को असाइन किए जाने से पहले हस्ताक्षरित प्रकार में परिवर्तित कर दिया जाएगा, और परिणाम हमेशा> = 0.

+0

लेकिन कीथ, फिर, 0x एफएफ एफएफ एफएफ एफएफ में एमएसबी है 1, जिसका उपयोग ऋणात्मक संख्याओं को दर्शाने के लिए किया जाता है, है ना? फिर हमने वास्तव में किस प्रकार के हस्ताक्षर किए गए int के चर के लिए ऋणात्मक मान निर्दिष्ट करके प्राप्त किया है? – n0nChun

+2

@ n0nChun: नकारात्मक संख्याओं का प्रतिनिधित्व करने का एकमात्र तरीका यह नहीं है। 2'-पूरक सबसे आम तरीका है; अन्य 1 एस-पूरक और साइन-और-आयाम हैं (सभी तीनों को सी मानक द्वारा अनुमत किया जाता है)। और मुद्दा यह है कि आप सचमुच * एक हस्ताक्षरित int को ऋणात्मक मान असाइन नहीं कर सकते हैं; किसी भी नकारात्मक मूल्य को पूरी तरह से परिवर्तित किया जाएगा, जिसके परिणामस्वरूप एक गैर-ऋणात्मक हस्ताक्षरित मूल्य होगा। इसके अलावा, 'हस्ताक्षरित int' आवश्यक नहीं है 32 बिट्स; यह 16 बिट्स जितना छोटा हो सकता है। '-1' हमेशा' UINT_MAX' में परिवर्तित हो जाएगा, जो आवश्यक रूप से '0xffffffff' नहीं है। –

+0

@ n0nChun एमएसबी का उपयोग अप्रयुक्त इनट्स में नकारात्मक संख्याओं को दर्शाने के लिए नहीं किया जाता है। यदि आप '% u' का उपयोग करते हैं, तो आप 2 * 0x7fffffff देखेंगे। हस्ताक्षरित इंट्स के लिए अधिकतम 2 गुना बड़ा है। – Daniel

6

हस्ताक्षर किए गए मान मुद्रित करने के लिए %d के बजाय %u का उपयोग करें। तो आपको 0xFFFFFFFF देखना चाहिए।

+0

मुझे पता है लेकिन मेरा जवाब नहीं देता प्रश्न – n0nChun

+1

एक हस्ताक्षरित int में -1 को असाइन करना केवल साइन बिट (0x7FF ...) को नहीं हटाता है, यह अभी भी 0xFF होगा ..., इस 'printf ("% 1 $ u: 0x% 1 $ X \ n" , एक्स); 'अपने आप को देखने के लिए। – Joe

+1

'x = -1' और' x = 0xFFFFFFFF' को वही चीज़ मिलनी चाहिए। 'x = 0x7FFFFFFF' एक अलग मान है, और आप इसे उपरोक्त किसी भी असाइनमेंट से नहीं प्राप्त करेंगे। यदि यह अभी भी इसे स्पष्ट नहीं करता है, तो मुझे यकीन नहीं है कि आप और क्या पूछ रहे हैं ... –

0

क्या हो रहा है यह है कि आप पहले मान को बिना हस्ताक्षरित int में परिवर्तित करते हैं, 0xffffffff को x को असाइन करते हैं। फिर printf ("% d \ n") का उपयोग करके आप मान को वापस हस्ताक्षरित int में परिवर्तित कर देंगे, फिर भी 0xffffffff के मान को बनाए रखें। इस प्रकार मुद्रण -1।

+2

बंद करें, लेकिन काफी नहीं । वह * परिवर्तित करता है * नहीं * मूल्य * रहता है (रूपांतरण निहित है, एक कास्ट ऑपरेटर के माध्यम से नहीं किया जाता है)। और 'printf' कॉल एक प्रकार का रूपांतरण नहीं करता है; बल्कि, यह शायद हस्ताक्षरित मूल्य के प्रतिनिधित्व की व्याख्या करता है जैसे कि यह एक हस्ताक्षरित मान (टाइप-पनिंग) था। ('Printf' कॉल के व्यवहार को कड़ाई से बोलना अनिर्धारित है।) –

+1

हाँ आप सही हैं, मैं गलत शब्द का उपयोग कर रहा हूं। जीसीसी से एएसएम आउटपुट को देखते हुए दो मूव दिखाए जाएंगे, जिसके परिणामस्वरूप मूल्य की व्याख्या होगी। – Rickard

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

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