2009-07-24 19 views
5

यह हस्ताक्षरित पूर्णांक के बिट्स के प्रतिनिधित्व के बारे में एक संदेह है। उदाहरण के लिए, जब आप -1 का प्रतिनिधित्व करना चाहते हैं, तो यह 2 के पूरक (+1) के बराबर है। तो -1 को 0xFFFFFFF के रूप में दर्शाया गया है। अब जब मैं 31 तक अपना नंबर बदलता हूं और परिणाम प्रिंट करता हूं तो यह -1 के रूप में वापस आ रहा है।बिट्स नकारात्मक संख्याओं का प्रतिनिधित्व

signed int a = -1; 
printf(("The number is %d ",(a>>31));//this prints as -1 

तो किसी को भी कैसे बिट्स ऋणात्मक संख्याओं के लिए प्रतिनिधित्व कर रहे हैं मुझे समझा कृपया कर सकते हैं?

धन्यवाद।

+0

इसे किसी अन्य कोण से देख रहे हैं: किसी भी एन-बिट (साइन-विस्तार) सही शिफ्ट को 2^एन से विभाजित करने के रूप में सोचें, नीचे घूमते हुए (शून्य से अनंतता की ओर, 0 की ओर नहीं) इसलिए -1 स्थानांतरित सही (संकेत के साथ) विस्तार) किसी भी समय उत्पादन -1 पर जारी रहेगा। – vladr

उत्तर

10

जब शीर्ष बिट शून्य है, तो संख्या सकारात्मक है। जब यह 1 है, संख्या नकारात्मक है।

ऋणात्मक संख्याएं संख्या को नकारात्मक रखने के लिए शीर्ष पर एक "1" स्थानांतरित करने के लिए सही स्थानांतरित हो गईं। यही कारण है कि आप वह जवाब प्राप्त कर रहे हैं।

दो के पूरक के बारे में अधिक जानकारी के लिए, this Stackoverflow question देखें।


@Stobor बताते हैं कि कुछ सी कार्यान्वयन के बजाय उच्च बिट में 0 बदलाव कर सकता है 1. की [विकिपीडिया में सत्यापित।] जावा में यह भरोसे के साथ अंकगणितीय पारी है।

लेकिन प्रश्नकर्ता द्वारा दिए गए आउटपुट से पता चलता है कि उनका कंपाइलर अंकगणितीय बदलाव कर रहा है।

+0

लेकिन y shud इसे -1 के रूप में प्रिंट करता है, इसे शीर्ष के बाद से 1 अनुष्ठान के रूप में प्रिंट करना चाहिए, लेकिन 1 है जो ऋणात्मक संख्या का प्रतिनिधित्व करता है। –

+1

@ नोसेरेना: आपको यह भी उल्लेख करना चाहिए कि भरने के साथ-साइन-बिट व्यवहार कार्यान्वयन विशिष्ट है। – Stobor

+0

चूंकि यह एक ऋणात्मक संख्या का प्रतिनिधित्व करता है, यह एक सकारात्मक संख्या क्यों मुद्रित करेगा? – Nosredna

1

यह एक अंकगणितीय शिफ्ट ऑपरेशन है जो साइन बिट को संरक्षित करता है और हस्ताक्षरित संख्या के मंटिसा भाग को स्थानांतरित करता है।

चियर्स

8

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

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

+0

या शिफ्ट के बाद यह शीर्ष बिट (या बिट्स) में "या" हो सकता है। – Nosredna

+0

सभी उत्तरों के लिए बहुत बहुत धन्यवाद। कृपया मुझे अभी भी अपने ड्यूबूट को अभी तक साफ़ नहीं किया गया है। तो क्या यह संकलक या हार्डवेयर विशिष्ट है ??? –

+2

@ मैडी: यह हार्डवेयर और कंपाइलर पर निर्भर करता है।उदाहरण के लिए, यदि किसी विशेष सीपीयू में केवल तार्किक शिफ्ट दाएं (एलएसआर) है और अंकगणितीय शिफ्ट दाएं (एएसआर) नहीं है, तो उस मशीन के लिए कंपाइलर्स एलएसआर का उपयोग करेंगे, न कि अस्तित्वहीन एएसआर। यह संकलक पर भी निर्भर करता है; यहां तक ​​कि यदि किसी मशीन में एएसआर और एलएसआर दोनों हैं, तो एक कंपाइलर लेखक कई कारणों से किसी भी हस्ताक्षरित और हस्ताक्षरित मात्राओं के लिए एलएसआर का उपयोग करने का निर्णय ले सकता है। यह तेज हो सकता है; यह अन्य प्लेटफ़ॉर्म के साथ संगत हो सकता है जहां एक ही कंपाइलर भी चलता है; यह हो सकता है कि संकलक लिखने वाला व्यक्ति एएसआर पसंद नहीं करता है। –

1

मूल रूप से दो प्रकार की सही शिफ्ट होती है। एक हस्ताक्षरित सही शिफ्ट और एक हस्ताक्षरित सही शिफ्ट। एक हस्ताक्षरित दायां शिफ्ट बिट्स को दाईं ओर स्थानांतरित कर देगा, जिससे कम से कम महत्वपूर्ण बिट खो जाएंगे, और सबसे महत्वपूर्ण बिट 0 के साथ प्रतिस्थापित किया जाएगा। हस्ताक्षरित दाएं शिफ्ट के साथ, बिट्स को दाईं ओर स्थानांतरित कर दिया जाता है, जिससे कम से कम महत्वपूर्ण बिट खो जाना चाहिए, और सबसे महत्वपूर्ण बिट संरक्षित किया जाना चाहिए। एक हस्ताक्षरित दायां शिफ्ट संख्या को दो की शक्ति से विभाजित करता है (स्थानांतरित स्थानों की संख्या के अनुरूप), जबकि एक हस्ताक्षरित शिफ्ट एक तार्किक स्थानांतरण अभियान है।

">>" ऑपरेटर एक अहस्ताक्षरित सही बदलाव करता है जब डेटा प्रकार है जिस पर वह चल रही है अहस्ताक्षरित है, और जब डेटा प्रकार है जिस पर वह चल रही है पर हस्ताक्षर किए है यह एक हस्ताक्षरित सही पारी प्रदर्शन करती है। तो, वांछित परिणाम प्राप्त करने के लिए आपको थोड़ा हेरफेर करने से पहले ऑब्जेक्ट को एक हस्ताक्षरित पूर्णांक प्रकार पर डालना है।

+0

हस्ताक्षरित पूर्णांक के लिए एक 'हस्ताक्षरित शिफ्ट' जरूरी नहीं है (हालांकि यह आमतौर पर इस तरह से किया जाता है) - यह संकलक और/या हार्डवेयर पर निर्भर करता है। –

+0

हाँ। ये सही है। मैं x86 के कुछ संस्करणों को चलाने और जीसीसी के साथ संकलित करने के लिए अच्छी तरह से व्यवहार किए गए लैपटॉप/डेस्कटॉप/सर्वर मशीनों पर इतने लंबे समय तक प्रोग्रामिंग कर रहा हूं कि वर्तमान आवेदन के लिए अनुमान क्या उचित हैं और वास्तव में मानक क्या है की गारंटी देता है। –

0

संपादित करें: अहस्ताक्षरित int कम से कम 32 बिट व्यापक है

unsigned int a = -1; 
printf(("The number is %d ",(a>>31));//this prints as -1 

हैं, तो आपके संकलक वास्तव में निर्माण करने के लिए अनुमति नहीं है: जब नीचे लिखा गया था, सवाल में कोड के रूप में लिखा गया था -1 के आउटपुट के रूप में (छोटे चेतावनी के साथ कि आप प्रिंटफ को पास करने से पहले int को हस्ताक्षरित मान कास्टिंग करना चाहिए)।

क्योंकि एक एक अहस्ताक्षरित int है, बताए -1 के लिए यह यह UINT_MAX का मूल्य (छोटी गैर-नकारात्मक मान -1 सापेक्ष UINT_MAX +1 अनुकूल के रूप में) देना चाहिए। जब तक आपके प्लेटफ़ॉर्म पर हस्ताक्षर किए गए int में कम से कम 32 बिट्स हों, तो 31 तक सही हस्ताक्षर किए गए मात्रा को स्थानांतरित करने का नतीजा UINT_MAX 2^31 से विभाजित होगा, जिसे int के भीतर फिट होना होगा। (यदि हस्ताक्षरित int 31 बिट्स या छोटा है, तो यह जो कुछ भी पसंद करता है उसका उत्पादन कर सकता है क्योंकि शिफ्ट का परिणाम अनिर्दिष्ट है)।

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