2009-06-26 7 views
7

(-1 >> 1) का परिणाम -1 क्यों है? मैं सी में काम कर रहा हूं, हालांकि मुझे नहीं लगता कि इससे कोई फर्क नहीं पड़ता।(-1 >> 1) == -1 - क्यों?

#include <stdio.h> 



int main() 
{ 
    int num1 = -1; 

    int num2 = (num1 >> 1); 

    printf("num1=%d", num1); 

    printf("\nnum2=%d", num2); 

    return 0; 
} 
+1

php "echo -1 >> 1;" में भी सच है – merkuro

+0

पायथन में भी, और जैसा कि उत्तर कहते हैं, यह संकेत को संरक्षित करने के लिए नकारात्मक संख्याओं को 1 से भरने के लिए समझ में आता है। –

उत्तर

23

क्योंकि हस्ताक्षर किए गए पूर्णांक two's complement नोटेशन में दर्शाए जाते हैं।

-111111111 होगा (यदि यह 8 बिट नंबर था)।

-1 >> 1 जाहिर संकेत फैली इतना है कि यह 11111111 बनी हुई है।यह व्यवहार कंपाइलर पर निर्भर करता है, लेकिन Microsoft के लिए, जब एक हस्ताक्षरित नंबर दाएं स्थानांतरित किया जाता है (>>) साइन बिट की प्रतिलिपि बनाई जाती है, तो एक हस्ताक्षरित संख्या को स्थानांतरित करते समय दाएं कोने में 0 का कारण बनता है।

+4

यह सी, नोट में अपरिभाषित व्यवहार है। – bdonlan

+11

यह अपरिभाषित व्यवहार नहीं है, यह कार्यान्वयन-परिभाषित है कि साइन-बिट हस्ताक्षरित दाएं-शिफ्ट में किया जाता है या नहीं। – rlbond

+3

उन लोगों के लिए जो इसे देखना चाहते हैं, सी 99 मानक में 6.5.7/5। –

1

संकेत विस्तार:

मैं समझ नहीं है कि मैं क्या याद कर रहा हूँ ...

यहाँ एक सी प्रोग्राम है जो calc करता है का एक उदाहरण है।

5

बिट एक ऋणात्मक संख्या स्थानांतरण सी में कार्यान्वयन-व्यवहार परिणाम अपने मंच पर निर्भर करेगा, और सैद्धांतिक रूप से पूरी तरह से अतर्कसंगत हो सकता है। सी 99 मानक (6.5.7.5) से:

ई 1 >> ई 2 का परिणाम ई 1 सही स्थानांतरित ई 2 बिट स्थिति है। यदि E1 में एक हस्ताक्षरित प्रकार है या यदि E1 में हस्ताक्षरित प्रकार और एक गैर-ऋणात्मक मान है, परिणाम का मान E1/ 2^E2 के अंश का अभिन्न हिस्सा है। यदि ई 1 के पास एक हस्ताक्षरित प्रकार है और नकारात्मक मान है, तो परिणामी मान कार्यान्वयन-डीआईएफएड है।

ऐसा होने का कारण सबसे अधिक संभावना है क्योंकि आपका कंपाइलर लागू करने के लिए x86 SAR (Shift अंकगणितीय दाएं) निर्देश का उपयोग करता है >>। इसका मतलब है कि साइन एक्सटेंशन होगा - मूल्य को स्थानांतरित होने के बाद सबसे महत्वपूर्ण बिट को नए एमएसबी में दोहराया जाएगा। intel manuals से:

पारी गणित सही (एसएआर) और पारी तार्किक सही (SHR) निर्देश गंतव्य संकार्य के टुकड़े सही करने के लिए (कम महत्वपूर्ण बिट स्थानों की ओर) पाली। प्रत्येक पारी गिनती के लिए, गंतव्य संकार्य के कम से कम महत्वपूर्ण बिट सीएफ ध्वज में स्थानांतरित कर दिया है, और सबसे महत्वपूर्ण बिट या तो सेट कर दिया जाता या अनुदेश प्रकार के आधार पर मंजूरी दे दी। एसएचआर निर्देश को सबसे महत्वपूर्ण बिट साफ़ करता है (इंटेल® 64 और आईए -32 आर्किटेक्चर सॉफ्टवेयर डेवलपर के मैनुअल, वॉल्यूम 1) में चित्र 7-8 देखें; एसएआर अनुदेश सेट या सबसे महत्वपूर्ण बिट को साफ करता है गंतव्य संकार्य में मूल मूल्य का चिह्न (सबसे महत्वपूर्ण बिट) के अनुरूप करने के लिए। वास्तव में, एसएआर अनुदेश unshifted मूल्य की संकेत (इंटेल 64 में देखते हैं चित्रा 7-9 और IA-32 आर्किटेक्चर सॉफ्टवेयर डेवलपर की मैनुअल, खंड 1 के साथ खाली बिट स्थिति के लिए स्थानांतरित कर दिया मूल्य भरता है)।

+1

उद्धृत मार्ग बताता है कि एक ऑपरेशन (10 >> -1) अपरिभाषित है। सही ऑपरेंड -1 है। – rlbond

+0

आह, मेरी गलती। ठीक कर देंगे। – bdonlan

+0

यह 6.5.7/5 है, 6.5.7/3 नहीं। –

3

जब आप सही स्थानांतरित करते हैं और बाएंस्टी बिट एक 1 होता है, तो कुछ प्लेटफ़ॉर्म/कंपाइलर 0 में लाएंगे और कुछ 1 को संरक्षित करेंगे और नया बाएं बिट थोड़ा 1 बनाएंगे। यह संख्या का संकेत इतना नकारात्मक रखता है संख्या ऋणात्मक रहती है और इसे साइन एक्सटेंशन कहा जाता है।

यदि आप ((unsigned) -1) >> 1 का प्रयास करते हैं, तो आप अंतर देखेंगे, जो एक हस्ताक्षरित सही शिफ्ट करेगा और इसलिए हमेशा 0 बिट में स्थानांतरित होगा।

11

एक Arithmetic right shift जब स्थानांतरण एक signed number संकेत सुरक्षित करेगा:

11111111 (-1) will stay 11111111 (-1) 

इसके विपरीत, एक Logical right shift संकेत को सुरक्षित नहीं करेगा:

11111111 (-1) will become 01111111 (127) 

आपका कोड स्पष्ट रूप से एक अंकगणितीय पारी करता है, तो साइन बिट (MSB) दोहराया जाता है। ऑपरेटर (>>) आपके द्वारा उपयोग किए जा रहे प्लेटफ़ॉर्म के कार्यान्वयन विवरण पर निर्भर करता है। ज्यादातर मामलों में, यह एक अंकगणितीय शिफ्ट है।

यह भी ध्यान दें कि 11111111 में प्रतिनिधित्व के आधार पर दो अलग-अलग अर्थ हो सकते हैं। यह उन तरीकों को भी प्रभावित करता है जिन्हें वे स्थानांतरित कर दिए जाएंगे।

  • अहस्ताक्षरित हैं, तो 11111111 सही करने के लिए यह स्थानांतरण संकेत को सुरक्षित नहीं करेगा क्योंकि MSB एक संकेत सा नहीं है 255 का प्रतिनिधित्व करता है।
  • हस्ताक्षर किए जाने पर, 11111111 प्रतिनिधित्व करता है -1। अंकगणित रूप से इसे दाईं ओर स्थानांतरित करने से संकेत सुरक्षित रहेगा।