2012-01-03 6 views
7

मुझे बाएं शिफ्ट से परिणाम मिल रहे हैं जिनके लिए मुझे स्पष्टीकरण नहीं मिला।बिना हस्ताक्षर किए गए char का परिणाम << unsigned char हस्ताक्षरित नहीं है char

unsigned char value = 0xff; // 1111 1111 
unsigned char = 0x01; // 0000 0001 

std::cout << "SIZEOF value " << sizeof(value) << "\n"; // prints 1 as expected 
std::cout << "SIZEOF shift " << sizeof(shift) << "\n"; // prints 1 as expected 

std::cout << "result " << (value << shift) << "\n"; // prints 510 ??? 

std::cout << "SIZEOF result " << sizeof(value << shift) << "\n"; // prints 4 ??? 

मैं परिणाम उम्मीद कर रहा था 1111 1110 होने के लिए, लेकिन इसके बजाय मैं 1 1111 1110 के मूल्य के साथ int (?) मिलता है।

एक हस्ताक्षरित चार के बिट्स को बाईं ओर कैसे स्थानांतरित किया जा सकता है ताकि बिट्स को छोटा कर दिया जा सके और नतीजा 1111 1110 हो?

जो मैं करने की कोशिश कर रहा हूं वह बाइट्स की श्रृंखला को पढ़ना और उन्हें अलग-अलग लंबाई (1-32 बिट्स) के पूर्णांक के रूप में समझना है।

F0  F5 
1111 0000 1111 0101 

हो सकता है

0F (first 4 bits) 
0F (next 8 bits) 
05 (last 4 bits) 

तथ्य यह है कि गणित पूर्णांक की तुलना में छोटे प्रकार के साथ नहीं किया जाता है के साथ क्या करना यह कुछ है?

+0

11111111 << 1 वास्तव में 111111110 है, आप अभिव्यक्ति का परिणाम प्रिंट कर रहे हैं, करने का प्रयास करें: 'value = value << shift; 'और फिर' cout << value; ' – Yaniro

उत्तर

9

2011 मानक के कुछ मसौदा का हवाला देते हुए:

5,8 शिफ्ट ऑपरेटर [expr.shift]

...

ऑपरेंड अभिन्न या अनिश्चित गणना प्रकार और अभिन्न प्रचार किए जाएंगे। परिणाम का प्रकार प्रचारित बाएं ऑपरेंड का है।

और

4,5 इंटीग्रल प्रचार [conv.prom]

एक पूर्णांक bool, char16_t, char32_t, या wchar_t जिसका पूर्णांक रूपांतरण रैंक (4.13) के अलावा अन्य प्रकार का एक prvalue है int के रैंक से कम टाइप int के प्रसार में परिवर्तित किया जा सकता है यदि int सभी स्रोत प्रकार के मानों का प्रतिनिधित्व कर सकता है; अन्यथा, स्रोत prvalue अहस्ताक्षरित पूर्णांक

प्रकार का एक prvalue करने के लिए परिवर्तित किया जा सकता है ...

तो, valueint के लिए प्रोत्साहित किया जाता है, और value << shift के प्रकार को बढ़ावा दिया बाईं संकार्य के प्रकार है , यानी int

आप अपने वांछित परिणाम प्राप्त कर सकते हैं इनमें से किसी एक:

std::cout << "result " << ((unsigned char)(value << shift)) << "\n"; 
std::cout << "result " << ((value << shift)&0xff) << "\n"; 
2

बस इसे वापस एक अहस्ताक्षरित चार करने के लिए डाली:

std::cout << "result " << static_cast<unsigned char>(value << shift) << "\n"; 

या, बिटवाइज़-और का उपयोग करें:

std::cout << "result " << ((value << shift) & 0xFF) << "\n"; 
2

आप बिट्स मुखौटा आप रुचि रखते हैं सकता है:

(value << shift) & 0xff 

क्या आप देख रहे हैं पूर्णांक पदोन्नति का परिणाम है , और भाषा का एक हिस्सा है। कल्पना करें कि आप 2-8-बिट वाले से 16-बिट पूर्णांक लिख रहे हैं - आप उच्च और निम्न बिट्स को सही जगह पर प्राप्त करने के लिए मैन्युअल रूप से उच्च चौड़ाई पूर्णांक को प्रचारित नहीं करना चाहते हैं, है ना?