आमतौर पर फ्लैग एनम को हेक्साडेसिमल मानों के साथ क्यों परिभाषित किया जाता है


121

बहुत बार मैं फ्लैग एनम घोषणाओं को देखता हूं जो हेक्साडेसिमल मूल्यों का उपयोग करते हैं। उदाहरण के लिए:

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

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

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

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


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

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

आप यहाँ कुछ निरर्थक कर रहे हैं। झंडे के पीछे इरादा यह है कि वे संयुक्त रूप से बिटवाइज़ होंगे। लेकिन बिटवाइज़ संयोजन प्रकार के तत्व नहीं हैं। मान Flag1 | Flag23 है, और 3 किसी भी डोमेन मान के अनुरूप नहीं है MyEnum
काज

आप ने उसे कहाँ देखा? प्रतिक्षेपक के साथ?
जियामिन

@giammin यह एक सामान्य प्रश्न है, विशिष्ट कार्यान्वयन के बारे में नहीं। आप ओपन सोर्स प्रोजेक्ट या उदाहरण के लिए नेट पर उपलब्ध कोड ले सकते हैं।
आदि लेस्टर

जवाबों:


183

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

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

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

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

13
+1 इस संकेतन के साथ आप कभी भी एनुम मान गणना में त्रुटि नहीं करते हैं
सर्गेई बेरेज़ोवस्की 21

1
@AllonGuralnek: कंपाइलर [फ्लैग] एनोटेशन को देखते हुए यूनिक बिट पोज़िशन्स असाइन करता है? आम तौर पर यह 0 से शुरू होता है और 1 के वेतन वृद्धि में जाता है, इसलिए 3 बिट्स (दशमलव) को किसी भी बिट सेट करते हुए बाइनरी में निर्धारित 3 (दशमलव) 11 होगा।
एरिक जे।

2
@ ईरिक: हुह, मुझे नहीं पता, लेकिन मैं हमेशा निश्चित था कि इसने दो की शक्तियों का मान प्रदान किया है। मैंने अभी जाँच की है, और मुझे लगता है कि मैं गलत था।
एलन ग्रेलनेक

38
x << yसंकेतन के साथ एक और मजेदार तथ्य । 1 << 10 = KB, 1 << 20 = MB, 1 << 30 = GBऔर पर इतना। यह वास्तव में अच्छा है यदि आप एक बफर के लिए 16 केबी सरणी बनाना चाहते हैं, तो आप बस जा सकते हैंvar buffer = new byte[16 << 10];
स्कॉट चैंबरलेन

43

यह देखना आसान बनाता है कि ये बाइनरी फ्लैग हैं।

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 मिलता है ... मुझे पढ़ना आसान लगता है। क्या मैं कुछ गड़बड़ कर रहा हूं?
लाइटस्टाइकर

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

2
@LightStriker बस इसे बाहर फेंकने जा रहा है जो कि अगर आप हेक्स का उपयोग नहीं कर रहे हैं तो इससे कोई फर्क नहीं पड़ता। केवल शून्य से शुरू होने वाले मानों की व्याख्या अष्टक के रूप में की जाती है। तो 012वास्तव में है 10
योनाथन रीनहार्ट

@JonathonRainhart: मुझे पता है। लेकिन मैं हमेशा bitfields का उपयोग करते समय हेक्स का उपयोग करता हूं। मुझे यकीन नहीं है कि मैं intइसके बजाय सुरक्षित महसूस करूंगा । मुझे पता है कि यह बेवकूफी है ... लेकिन आदतें मुश्किल से मरती हैं।
लाइटस्ट्राइकर

36

मुझे लगता है कि यह सिर्फ इसलिए है क्योंकि अनुक्रम हमेशा 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

और इसी तरह, जब तक आप क्रम को 1-2-4-8 याद रखते हैं, तब तक आप बाद की सभी झांकियों को 2 की शक्तियों को याद किए बिना बना सकते हैं।


13

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


2
बिटवाइज़ ऑपरेशंस का उपयोग करने की क्षमता का वास्तव में झंडे की विशेषता से कोई लेना-देना नहीं है।
मैटियास नॉर्डकविस्ट

4

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


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

3

क्योंकि जहां ध्वज में बिट्स हैं, उन मनुष्यों के लिए पालन करना आसान है। प्रत्येक हेक्साडेसिमल अंक 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

यह स्पष्टीकरण अच्छा है .... केवल एक चीज गायब है जो कि बिट,
नीबल्स
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.