2012-11-04 7 views
101

कई बार मैं ध्वज enum घोषणाओं को देखता हूं जो हेक्साडेसिमल मानों का उपयोग करते हैं। उदाहरण के लिए:फ्लैग एनम्स आमतौर पर हेक्साडेसिमल मानों के साथ परिभाषित क्यों होते हैं

[Flags] 
public enum MyEnum 
{ 
    None = 0x0, 
    Flag1 = 0x1, 
    Flag2 = 0x2, 
    Flag3 = 0x4, 
    Flag4 = 0x8, 
    Flag5 = 0x10 
} 

जब मैं एक enum की घोषणा, मैं आमतौर पर इसे इस तरह की घोषणा:

[Flags] 
public enum MyEnum 
{ 
    None = 0, 
    Flag1 = 1, 
    Flag2 = 2, 
    Flag3 = 4, 
    Flag4 = 8, 
    Flag5 = 16 
} 

एक कारण या क्यों कुछ लोग दशमलव के बजाय हेक्साडेसिमल में मूल्य लिखने के लिए चयन करने के लिए तर्क है ? जिस तरह से मैं इसे देखता हूं, हेक्स मानों का उपयोग करते समय उलझन में जाना आसान होता है और Flag5 = 0x10 के बजाय गलती से Flag5 = 0x16 लिखना आसान होता है।

+4

यदि आपने दशमलव संख्याओं का उपयोग किया है तो आप '0x10' के बजाय' 10' लिखेंगे? विशेष रूप से ये बाइनरी संख्याएं हैं जिनसे हम काम कर रहे हैं, और हेक्स बाइनरी से/छोटे रूप से परिवर्तनीय है? '0x111'' 273' से किसी के सिर में अनुवाद करने के लिए बहुत कम परेशान है ... – cHao

+4

यह एक शर्म की बात है कि सी # में एक वाक्यविन्यास नहीं है जिसे स्पष्ट रूप से दो की शक्तियों को लिखने की आवश्यकता नहीं है। –

+0

आप यहां कुछ बकवास कर रहे हैं। झंडे के पीछे का इरादा यह है कि वे थोड़ा सा संयुक्त होंगे। लेकिन bitwise संयोजन प्रकार के तत्व नहीं हैं। मान 'फ्लैग 1 | Flag2' 3 है, और 3 'MyEnum' के किसी भी डोमेन मान से मेल नहीं खाता है। – Kaz

उत्तर

160

तर्कसंगत भिन्न हो सकते हैं, लेकिन मुझे लगता है कि हेक्साडेसिमल आपको याद दिलाता है: "ठीक है, हम बेस दस की मनमानी मानव आविष्कारशील दुनिया में संख्याओं से निपट नहीं रहे हैं। हम बिट्स से निपट रहे हैं - मशीन दुनिया - और हम इसके नियमों से खेलेंगे। " हेक्साडेसिमल का शायद ही कभी उपयोग किया जाता है जब तक आप अपेक्षाकृत कम-स्तरीय विषयों से निपट नहीं रहे हैं जहां डेटा के मेमोरी लेआउट मायने रखता है। इसका उपयोग इस तथ्य पर संकेत देता है कि यह वह स्थिति है जहां हम अभी हैं।

इसके अलावा, मुझे सी # के बारे में निश्चित नहीं है, लेकिन मुझे पता है कि सी x << y में एक वैध संकलन-समय स्थिर है। सा बदलाव का उपयोग करना सबसे स्पष्ट लगता है: एक यांत्रिक, सरल हेक्स में एक शक्ति के-दो दोगुना करने के लिए जिस तरह से है

[Flags] 
public enum MyEnum 
{ 
    None = 0, 
    Flag1 = 1 << 0, 
    Flag2 = 1 << 1, 
    Flag3 = 1 << 2, 
    Flag4 = 1 << 3, 
    Flag5 = 1 << 4 
} 
+6

यह बहुत दिलचस्प है और यह वास्तव में एक वैध सी # enum भी है। –

+13

+1 इस नोटेशन के साथ आप एनम वैल्यू कैलकुलेशन में कभी भी त्रुटि नहीं करते हैं –

+0

@lazyberezovsky: या आप केवल मानों को छोड़ सकते हैं और कंपाइलर को असाइन कर सकते हैं - यहां तक ​​कि कम त्रुटि प्रवण भी। लेकिन यह वास्तव में अच्छा है जब आपको स्पष्ट रूप से मूल्य निर्धारित करना होगा। –

34

यह देखना आसान बनाता है कि ये बाइनरी झंडे हैं।

None = 0x0, // == 00000 
Flag1 = 0x1, // == 00001 
Flag2 = 0x2, // == 00010 
Flag3 = 0x4, // == 00100 
Flag4 = 0x8, // == 01000 
Flag5 = 0x10 // == 10000 

हालांकि प्रगति यह भी स्पष्ट करता है:

Flag6 = 0x20 // == 00100000 
Flag7 = 0x40 // == 01000000 
Flag8 = 0x80 // == 10000000 
+3

मैं वास्तव में 0x1, 0x2, 0x4, 0x8 के सामने 0 जोड़ता हूं ... इसलिए मुझे 0x01, 0x02, 0x04, 0x08 और 0x10 मिलते हैं ... मुझे पढ़ने में आसान लगता है। क्या मैं कुछ गड़बड़ कर रहा हूँ? – LightStriker

+4

@ लाइट - बिलकुल नहीं। यह बहुत आम है ताकि आप देख सकें कि ये कैसे संरेखित हैं। बस बिट्स को और स्पष्ट बनाता है :) – Oded

+0

बहुत बहुत धन्यवाद। जानकार अच्छा लगा। – LightStriker

11

क्योंकि [Flags] मतलब यह है कि वास्तव में एक enum bitfield है। [Flags] के साथ आप झटके को गठबंधन करने के लिए bitwise और (&) और OR (|) ऑपरेटर का उपयोग कर सकते हैं। इस तरह बाइनरी मानों से निपटने पर, हेक्साडेसिमल मानों का उपयोग करने के लिए यह लगभग हमेशा स्पष्ट होता है। यही कारण है कि हम पहले स्थान पर hexadecimal का उपयोग करते हैं। प्रत्येक हेक्स चरित्र बिल्कुल एक निबल (चार बिट्स) से मेल खाता है। दशमलव के साथ, यह 1-टू -4 मैपिंग सही नहीं है।

+1

बिटवाई ऑपरेशंस का उपयोग करने की क्षमता में वास्तव में ध्वज विशेषता के साथ कुछ लेना देना नहीं है। –

3

क्योंकि। दशमलव में, यह मुश्किल है। इसके लिए आपके सिर में लंबे गुणा की आवश्यकता है। हेक्स में यह एक साधारण परिवर्तन है। आप 1UL << 63 तक इसे सभी तरह से ले जा सकते हैं जो आप दशमलव में नहीं कर सकते हैं।

+1

मुझे लगता है कि यह सबसे अधिक समझ में आता है। मानों के बड़े सेट के साथ enums के लिए यह जाने का सबसे आसान तरीका है (@ हाइपरक्यूब के उदाहरण के संभावित अपवाद के साथ)। –

2

क्योंकि मनुष्यों के लिए यह पालन करना आसान है जहां बिट्स ध्वज में हैं। प्रत्येक हेक्साडेसिमल अंक 4 बिट बाइनरी फिट कर सकता है।

0x0 = 0000 
0x1 = 0001 
0x2 = 0010 
0x3 = 0011 

... and so on 

0xF = 1111 

आमतौर पर आप, कर रहे हैं और यह हेक्साडेसिमल मान उपयोग कर रहा है अपने झंडे की घोषणा करने के चित्रण के लिए सबसे आसान तरीका अपने झंडे बिट्स ओवरलैप नहीं करना चाहते हैं।

इसलिए, यदि आप 16 बिट्स के साथ झंडे की जरूरत है आप 4 अंक हेक्साडेसिमल मान का उपयोग करेगा और इस तरह आप गलत मूल्यों से बच सकते हैं:

0x0001 //= 1 = 000000000000 0001 
0x0002 //= 2 = 000000000000 0010 
0x0004 //= 4 = 000000000000 0100 
0x0008 //= 8 = 000000000000 1000 
... 
0x0010 //= 16 = 0000 0000 0001 0000 
0x0020 //= 32 = 0000 0000 0010 0000 
... 
0x8000 //= 32768 = 1000 0000 0000 0000 
+0

यह स्पष्टीकरण अच्छा है ....केवल एक चीज गायब है, बिट, निबल्स और बाइट्स की अंतिम रेखा को दिखाने के लिए बराबर बाइनरी है;) – GoldBishop

27

मुझे लगता है कि अनुक्रम हमेशा होता है सिर्फ इसलिए कि 1,2,4 यह है , 8 और फिर 0 जोड़ें।
आप देख सकते हैं:

0x1 = 1 
0x2 = 2 
0x4 = 4 
0x8 = 8 
0x10 = 16 
0x20 = 32 
0x40 = 64 
0x80 = 128 
0x100 = 256 
0x200 = 512 
0x400 = 1024 
0x800 = 2048 

और इतने पर, जब तक आप 2

की शक्तियों को याद करने के बिना अनुक्रम 1-2-4-8 आप बाद के सभी झंडे निर्माण कर सकते हैं याद के रूप में
+0

वाह। वहाँ बिल्कुल महान छोटी चाल है। इसे प्यार करना। –