2012-06-04 25 views
7

मैं जिस भाषा का उपयोग करता हूं वह है सी एक्स और एन का प्रकार int है।~ (x-1) और ~ x + 1 के बीच का अंतर x = 0x80000000

मैं यह एक्स का मान से पता चलता n और एक्स के पूरक संख्या के n बिट्स स्थानांतरण के दो तरीके के रूप में निम्नलिखित

printf("x=%x,n=%d,first=%x,second=%x\n",x,n,((~(x+0xffffffff))>>n),((~x+1)>>n)); 

एक लाइन कोड है। जब x = 0x80000000, ~ (x + 0xffffffff) = 0x8000000, ~ x + 1 = 0x80000000, फिर भी इन दोनों को बिट्स द्वारा स्थानांतरित करते समय, परिणाम अलग-अलग होते हैं।

btw, अगर मैं (~ 1 + 1 के 0xffffffff बदल इसका मतलब है कि ~ (x + (~ 1 + 1)), परिणाम के रूप में ~ x + 1

मुझे आश्चर्य है कि ऐसा क्यों हुआ। धन्यवाद एक ही है ।

+0

[है "(uint16_t) -1" पोर्टेबल सी कोड?] (Http://embeddedgurus.com/barr-code/2011/06/is-uint16_t-1-portable-c-code/) – Lundin

+0

@ लंदन वह लेख गलत है। '(uint16_t) -1' ** **' 0xFFFF' उत्पादन करने के लिए मानक द्वारा गारंटीकृत है यदि कार्यान्वयन उस प्रकार को 'stdint.h' में प्रदान करता है। (बेशक, अगर यह आपकी खुद की टाइपिफ़ी है तो कुछ भी गारंटी नहीं दी जाती है।) कोई अस्पष्टता नहीं है, निश्चित चौड़ाई वाले प्रकारों में कोई पैडिंग बिट्स की आवश्यकता नहीं होती है, इसलिए यह मूल्य बिट्स तक भी सीमित नहीं है (ठीक है, यह तब से है 'uintN_t' में केवल मूल्य बिट्स हैं)। –

उत्तर

4

अब पवन मंजुनाथ के हटाए गए उत्तर का एक मामला सही जवाब था, यह मानते हुए कि int सामान्य रूप से 32-बिट प्रकार है। पूर्णांक लगातार

0xffffffff 

मूल्य 2^32 - 1 है और जो किसी int द्वारा प्रदर्शनीय नहीं है, लेकिन यह एक unsigned int के रूप में प्रदर्शनीय है। तो इसका प्रकार unsigned int (6.4.4.1) है। इसलिए x इसके लिए unsigned int में बदल जाती है, और

((~(x+0xffffffff))>>n) 

का मूल्यांकन करता है के रूप में

((~(0x80000000u + 0xffffffffu)) >> n) 
((~0x7fffffffu) >> n) 
(0x80000000u >> n) 
मूल्य के साथ

2^(31-n)0 <= n < 32 अगर (यह अनिर्धारित व्यवहार अगर n कि सीमा के बाहर है)।

अन्य मामले के लिए, ouah का जवाब जब x = 0x80000000 एक int, ~0x8000000 = 0x7fffffff = INT_MAX और INT_MAX + 1 पर हस्ताक्षर किए पूर्णांक अतिप्रवाह के रूप में अपरिभाषित व्यवहार है, सही है।

फिर भी, एक आम व्यवहार लपेटता है, और उसके बाद परिणाम का परिणाम हस्ताक्षर पूर्णांक 0x80000000 है और नकारात्मक पूर्णांक का दायां स्थानांतरण स्थानांतरण-परिभाषित व्यवहार (6.5.7) है। सामान्य साइन-एक्सटेंशन के साथ स्थानांतरित हो रहा है, जो परिणाम -2^(31-n) उत्पन्न करेगा, जिसे unsigned int के रूप में 2^32 - 2^(31-n) के साथ printf रूपांतरण विनिर्देश %x द्वारा मूल्य के साथ समझा जाएगा।

+0

~ 0 हस्ताक्षरित या हस्ताक्षरित है ... – shirley

+0

'0'' int' के रूप में प्रतिनिधित्व योग्य है, इसलिए '~ 0' का प्रकार' int' भी है। –

1

जब एक्स = 0x80000000, ~ (x + 0xffffffff) = 0x8000000, ~ x + 1 = 0x80000000,

32-बिट int के साथ एक प्रणाली पर (यह मानते हुए x प्रकार int की है) और दो के पूरक हस्ताक्षर प्रतिनिधित्व, यह अभिव्यक्ति:

~x+1 

अपरिभाषित व्यवहार है। x = 0x80000000 का अर्थ है ~x == 0x7FFFFFFF == INT_MAX और INT_MAX + 1 अपरिभाषित व्यवहार है। तो ~x + 10x80000000 या कुछ और हो सकता है।

यह अभिव्यक्ति:

~(x+0xffffffff) 

दूसरी ओर परिभाषित किया गया है (0xffffffff सी में unsigned int है) और 0x80000000 के बराबर है। यह वास्तव में परिभाषित किया गया है क्योंकि 0xffffffffunsigned int है और सी मानक की भावना में हस्ताक्षर किए गए पूर्णांक कभी नहीं बहते हैं।

इसका मतलब यह है कि इस बयान:

printf("x=%x,n=%d,first=%x,second=%x\n",x,n,((~(x+0xffffffff))>>n),((~x+1)>>n)); 

अपरिभाषित व्यवहार का आह्वान और यह दोनों परिणामों की तुलना करने कोई मतलब नहीं है।

0

(माना जाता है आकार (int) 4 है, यानी, 32 बिट हस्ताक्षरित मूल्य)। 0x80000000; // -+२१४७४८३६४८ जो छोटी संभव है नकारात्मक पूर्णांक 0xFFFFFFFF // है -1

दो (पूर्णांक का उपयोग कर गणित) का योग है, जोड़ा जा रहा है दोनों एक साथ का कारण बनता है एक नकारात्मक से सकारात्मक 0x7FFFFFFF करने के लिए 'लपेट' है जो 2147483647

'~' 0x7FFFFFFF पर ऑपरेटर का उपयोग करना पैदावार थोड़ा-वार completent, या 0x80000000

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

अपने मामले में, आप इस सीमित मामले के बारे में बहुत सावधान किए बिना हस्ताक्षर किए गए अंकगणित और बिटवाई ऑपरेटरों को मिश्रण करने की उम्मीद नहीं कर सकते हैं।

यह भी ध्यान दें कि 2 के पूरक अंकगणितीय का उपयोग करते समय असमानता है: सकारात्मक से एक और नकारात्मक संख्या है (क्योंकि आपको शून्य का प्रतिनिधित्व करने की आवश्यकता है, जो शेष मूल्यों के लिए अन्य बिट प्रतिनिधित्वों की एक विषम संख्या छोड़ देता है।)