2011-09-22 12 views
15

मेरी संकलक, निम्नलिखित छद्म कोड पर (मूल्यों बाइनरी के साथ प्रतिस्थापित):सही पारी और हस्ताक्षर किए पूर्णांक

(11111111 11111111 10000000 00000000) 

मेरा प्रश्न:

sint32 word = (10000000 00000000 00000000 00000000); 
word >>= 16; 

एक bitfield कि इस तरह दिखता है के साथ एक word का उत्पादन क्या, क्या मैं इस प्लेटफॉर्म और सी ++ कंपाइलर्स के लिए इस व्यवहार पर भरोसा कर सकता हूं?

उत्तर

23

नीचे दिए गए लिंक से:
INT34-C. Do not shift an expression by a negative number of bits or by greater than or equal to the number of bits that exist in the operand

अनुपालन न करने संहिता उदाहरण (सही शिफ्ट)
E1 >> E2 का परिणाम E1 सही-स्थानांतरित E2 बिट पदों है। यदि E1 में एक हस्ताक्षरित प्रकार है या E1 पर एक हस्ताक्षरित प्रकार और एक गैर-ऋणात्मक मान है, तो परिणाम का मान E1/2 ई 2 के अंश का अभिन्न हिस्सा है। E1 एक हस्ताक्षरित प्रकार और एक नकारात्मक मूल्य होता है, तो परिणामस्वरूप मूल्य कार्यान्वयन परिभाषित और या तो एक गणित हो सकता है (हस्ताक्षरित) पारी:
Arithmetic (signed) shift
या एक तार्किक (अहस्ताक्षरित) पारी:
Logical (unsigned) shift
यह अनुपालन न करने कोड उदाहरण यह जांचने में विफल रहता है कि सही ऑपरेंड प्रचारित बाएं ऑपरेंड की चौड़ाई से अधिक या बराबर है, जो अनिर्धारित व्यवहार की अनुमति देता है।

unsigned int ui1; 
unsigned int ui2; 
unsigned int uresult; 

/* Initialize ui1 and ui2 */ 

uresult = ui1 >> ui2; 

के बारे में सही बदलाव अंकगणितीय रूप में लागू किया गया है या नहीं बनाना मान्यताओं (हस्ताक्षरित) पारी या एक तार्किक (अहस्ताक्षरित) पारी भी कमजोरियों को जन्म दे सकता। सिफारिश INT13-C. Use bitwise operators only on unsigned operands देखें।

+1

क्या कोई सिफारिश नहीं थी जो वास्तव में इस मुद्दे पर केंद्रित थी? क्योंकि उस नियम के नाम पर आधारित, यह यहां लागू नहीं होता है ... आप केवल कुछ उपलब्ध पृष्ठभूमि जानकारी उद्धृत कर रहे हैं। –

12

नहीं, आप इस व्यवहार पर भरोसा नहीं कर सकते हैं। नकारात्मक मात्राओं का सही स्थानांतरण (जो मुझे लगता है कि आपका उदाहरण कार्य कर रहा है) कार्यान्वयन परिभाषित किया गया है।

+0

ठीक है, यह उचित है। मुझे अभी भी आश्चर्य है, अगर संकलक एक बाइनरी बनाता है जो इस विधि का उपयोग करता है, तो क्या यह कम से कम अधिकांश हार्डवेयर में अपेक्षित काम करेगा? –

+4

यदि आप किसी निश्चित आर्किटेक्चर के लिए कुछ संकलित करते हैं, तो उसे उस आर्किटेक्चर के सभी कार्यान्वयन में समान कार्य करना चाहिए। x86, उदाहरण के लिए, साइन-एक्सटेंशन और गैर-साइन-एक्सटेंशन शिफ्ट के लिए अलग-अलग शिफ्ट ऑपरेशन हैं, और यह संकलक है जो तय करता है कि किस का उपयोग करना है। यह शायद अन्य आर्किटेक्चर पर बिल्कुल भी काम नहीं करेगा (पढ़ें: * कुछ भी *, केवल इस व्यवहार से नहीं)। –

+0

यह भयानक है ... – Claudiu

3

AFAIK पूर्णांक को सी ++ में साइन-आयाम के रूप में दर्शाया जा सकता है, जिसमें मामले का विस्तार एक्सटेंशन 0 से भर जाएगा। तो आप इस पर भरोसा नहीं कर सकते हैं।

+0

आप सही हैं। मानक कुछ आवश्यकताओं को बनाता है जो दो के पूरक को इष्टतम प्रतिनिधित्व करते हैं, लेकिन सामान्य रूप से, कार्यान्वित पूर्णांक को कार्यान्वित करने के किसी भी तरीके से प्रदर्शित किया जा सकता है। –

6

सी ++ में, नहीं। यह कार्यान्वयन और/या मंच निर्भर है।

कुछ अन्य भाषाओं में, हाँ। जावा में, उदाहरण के लिए, >> ऑपरेटर को हमेशा बाएं सबसे अधिक उपयोग करके भरने के लिए परिभाषित किया जाता है (इस प्रकार चिह्न को संरक्षित करता है)। >>> ऑपरेटर 0s का उपयोग भरता है। तो यदि आप विश्वसनीय व्यवहार चाहते हैं, तो एक संभावित विकल्प एक अलग भाषा में बदलना होगा। (हालांकि जाहिर है, यह आपकी परिस्थितियों के आधार पर एक विकल्प नहीं हो सकता है।)

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