2011-03-29 20 views
9

नीचेभंडारण ऋणात्मक संख्याओं

int main() 
{ 
int a = -1; 
printf("%d",a>>1); 
return 0; 
} 

इस कोड में ऐसा क्यों है उत्पादन दे रहा है -1।

+1

इस प्रश्न को देखें [सी में ऑपरेटर शिफ्ट] (http://stackoverflow.com/questions/7622/shift-operator-in-c)। – Mat

उत्तर

12

बिट-स्थानांतरण केवल हस्ताक्षरित प्रकारों पर परिभाषित किया गया है, हस्ताक्षरित प्रकारों के लिए यह कार्यान्वयन-परिभाषित है। और यह अनुसंधान द्वारा एक उपयोगी शोधन होता है ..

सच पूछिये तो, यह जब भी मूल्य सकारात्मक है और परिणाम नहीं अतिप्रवाह करता है, और सही बदलाव के लिए कार्यान्वयन परिभाषित किया गया है पर हस्ताक्षर किए प्रकार के लिए परिभाषित किया गया है नकारात्मक मूल्य। वाम पारी दूसरे हाथ पर,, ऋणात्मक मानों

┌───┬──────────────┬──────────────────────────────────┬────────────────────────┐ 
│ │ Unsigned  │ Signed, positive     │ Signed, negative  │ 
├───┼──────────────┼──────────────────────────────────┼────────────────────────┤ 
│<< │ well-defined │ well-defined, except on overflow │ undefined behaviour │ 
│>> │ well-defined │ well-defined      │ implementation-defined │ 
└───┴──────────────┴──────────────────────────────────┴────────────────────────┘ 
+4

कड़ाई से बोलते हुए, जब भी मान सकारात्मक होता है तो हस्ताक्षरित प्रकारों के लिए परिभाषित किया जाता है और परिणाम अधिक नहीं होता है, और सही शिफ्ट कार्यान्वयन-नकारात्मक मानों के लिए परिभाषित किया जाता है। बाईं तरफ, बाएं शिफ्ट, नकारात्मक मानों के लिए * अपरिभाषित * है। –

+1

मेरा मानना ​​है कि सी 99 में [कार्यान्वयन-परिभाषित "होगा [विकिपीडिया: अंकगणितीय शिफ्ट] (http: //en.wikipedia।संगठन/विकी/अंकगणितीय_शिफ्ट) – Mat

5

के लिए अपरिभाषित है क्योंकि -1 है 1111111 ... 111 बाइनरी में। a>>1 ऑपरेशन साइन बिट "साइन इन" करेगा, इसलिए आपको 1111111 ... 111 फिर मिलेगा।

+0

यह केवल पूरक कोड में है, जो जरूरी नहीं है कि जिस तरह से संख्याओं का प्रतिनिधित्व किया जाता है। लेकिन फिर भी, कई प्लेटफार्मों पर आप सही हैं –

+0

@ आर्टमेंट - सहमत, यह निश्चित रूप से मशीन निर्भर है। मुझे यह इंगित करना चाहिए था। स्पष्ट रूप से, हालांकि, इस विशेष मामले में क्या हो रहा है, यह संकेत है। –

+0

@ आर्मेन - पता नहीं है कि आपको पिछली टिप्पणी मिली है या नहीं। (क्षमा करें, आपके नाम पर टाइपो।) –

1

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

0

>> ऑपरेटर एक हस्ताक्षरित मूल्य पर ऑपरेटर संकलक के आधार पर अंकगणितीय या तार्किक बदलाव कर सकता है। अंकगणितीय बदलाव साइन बिट को बरकरार रखते हैं, इसलिए -1 (जो कि 2-एस पूरक मशीन पर है, जो इन दिनों बहुत अधिक विविधता का सामना करेंगे) -1 सही स्थानांतरित होने पर बने रहेगा। (ध्यान दें कि सी मानक स्पष्ट रूप से निर्दिष्ट नहीं करता है कि हस्ताक्षरित संख्या पर >> एक अंकगणितीय या तार्किक बदलाव है। हालांकि यह हमेशा हस्ताक्षरित संख्याओं पर एक तार्किक बदलाव है।)

0

हस्ताक्षरित मानों पर बिट-स्थानांतरण की परिभाषा है कार्यान्वयन पर निर्भर। अपने कंपाइलर के दस्तावेज़ों को जांचें कि यह इसे कैसे संभालता है।

0

मेमोरी पर हस्ताक्षर पूर्णांक संख्या 2 के पूरक के रूप में संग्रहीत की जाती है यदि साइन int और जब स्मृति स्मृति से डेटा पढ़ा जाता है {% d} इसे मूल रूप में परिवर्तित कर दिया जाता है, तो यहां 2 का पूरक -1 स्मृति में संग्रहीत होगा, मान लें कि पूर्णांक 2 बाइट लेता है 2's complement of -1 is 1111 1111 1111 1111

के बाद प्रदर्शन a>>1 अब यह 0111 1111 1111 1111 बदल जाएगा कि हम जानते हैं कि जब डेटा स्मृति से पढ़ा जाता है इसे फिर से 0 पूरक में बदला न गया तो 0111 1111 1111 1111 के 2 के पूरक ले यह -1 1000 0000 0000 0001 जो बराबर है तरह होगा

नोट: 2 का पूरक +ve संख्या मूल बाइनरी प्रतिनिधित्व 2 के पूरक के समान है केवल -ve संख्या के लिए है। सी संख्या हमेशा 2 के पूरक फॉर्म

+1

पहले, हस्ताक्षरित संख्या 2 के पूरक के रूप में संग्रहीत नहीं हैं। हस्ताक्षरित संख्याओं के लिए, सभी आर्किटेक्चर/कंपाइलर कार्यान्वयन 2 के पूरक का भी उपयोग नहीं करते हैं। सी मानक किसी भी अन्य संख्या एन्कोडिंग के लिए अनुमति देता है हालांकि आज के –

+0

@ LưuVĩnhPhúc: यह आउटपुट क्यों आ रहा है -1 अगर हस्ताक्षर 2 के पूरक के रूप में संग्रहीत नहीं किया गया है तो # शून्य मुख्य() { हस्ताक्षरित int एक = -1; printf ("% d", ए); } –

+0

हस्ताक्षरित संख्या '% u' द्वारा मुद्रित की जाती हैं, आपको एक अपरिभाषित व्यवहार मिल रहा है –

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