2009-03-31 11 views
13

मैं द्विआधारी स्थिरांकसी ++ द्विआधारी लगातार/शाब्दिक

template< unsigned long long N > 
struct binary 
{ 
    enum { value = (N % 10) + 2 * binary<N/10> :: value } ; 
}; 

template<> 
struct binary<0> 
{ 
    enum { value = 0 } ; 
}; 

अनुमति देने के लिए तो तुम द्विआधारी < 101,011,011> :: मूल्य की तरह कुछ कर सकते हैं एक प्रसिद्ध टेम्पलेट का उपयोग कर रहा हूँ। दुर्भाग्य से यह एक हस्ताक्षरित लंबे समय के लिए 20 अंकों की सीमा है।

क्या किसी के पास बेहतर समाधान है?

+0

20 की सीमा शायद संकलक निर्भर है। यह इस बात पर निर्भर करता है कि यह कितना टेम्प्लेट रिकर्सन सहन करेगा। कुछ आधुनिक कंपाइलर्स आपको अधिकतम टेम्पलेट रिकर्सन गहराई को सेट करने के लिए तर्क में प्रवेश करने की अनुमति देंगे। –

+3

हालांकि, सीमा उस दशमलव अंकों की संख्या के कारण थी जो आप बिना हस्ताक्षरित लंबे समय तक स्टोर कर सकते थे, क्योंकि यह मूल रूप से * दशमलव * संख्या 101011011 ले रहा है और इसे बाइनरी में बदल रहा है, हां? – paxdiablo

+0

पैक्स: हाँ, कम से कम जीसीसी के लिए जिसका मैं उपयोग कर रहा हूं। – Unknown

उत्तर

25

हो सकता है यह काम करता है आप अपने द्विआधारी मूल्य पर एक अग्रणी शून्य है या नहीं? एक अग्रणी शून्य दशमलव के बजाय निरंतर ऑक्टल बनाता है।

जो इस समाधान से कुछ और अंक निचोड़ने का एक तरीका बनता है - हमेशा शून्य के साथ अपने बाइनरी स्थिरता को शुरू करें! फिर 10 के साथ अपने टेम्पलेट में 10 की जगह बदलें।

+2

ओह, यह चुस्त है :-) ब्रावो। – paxdiablo

+1

धन्यवाद दोस्तों, आपने मेरी रात बनाई है! –

4

सी ++ 0x user-defined literals है, जिसका उपयोग आप जो भी कर रहे हैं उसे लागू करने के लिए उपयोग किया जा सकता है।

अन्यथा, मुझे नहीं पता कि इस टेम्पलेट को कैसे सुधारें।

+0

क्या आप एक उदाहरण दे सकते हैं। – Unknown

+0

निश्चित रूप से, यहां एक उदाहरण है: http://stackoverflow.com/questions/537303/binary-literals/538101#538101 –

5

दृष्टिकोण मैं हमेशा का उपयोग किया है, हालांकि तुम्हारा के रूप में के रूप में सुंदर नहीं:

1/बस हेक्स का उपयोग करें। थोड़ी देर बाद, आपको पता चलेगा कि हेक्स अंक किस बिट पैटर्न का प्रतिनिधित्व करते हैं।

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

#define b0 0x00000001 
#define b1 0x00000002 
: : : 
#define b31 0x80000000 

unsigned long x = b2 | b7 

3/यदि प्रदर्शन महत्वपूर्ण नहीं है और पठनीयता के लिए महत्वपूर्ण है, तो आप इसे कार्यावधि में बस कर सकते हैं इस तरह के रूप में एक समारोह के साथ "एक्स = सेबिन (" 101011011 ");"।

4/एक स्नीकी समाधान के रूप में, आप एक प्री-प्री-प्रोसेसर लिख सकते हैं जो आपके * .cppme फ़ाइलों के माध्यम से जाता है और सभी "0b101011011" -टाइप स्ट्रिंग्स को उनके समकक्ष "0x15b" के साथ टाइप करके * .cpp को बनाता है। तार)। मैं इसे हल्के ढंग से नहीं करूँगा क्योंकि सिंटैक्स के सभी जटिल संयोजनों के बारे में आपको चिंता करनी पड़ सकती है। लेकिन यह आपको अपनी स्ट्रिंग लिखने की अनुमति देगा क्योंकि आप कंपाइलर की अनियमितताओं के बारे में चिंता किए बिना चाहते हैं, और आप सावधानीपूर्वक कोडिंग द्वारा सिंटैक्स चाल को सीमित कर सकते हैं।

बेशक

, उसके बाद अगले कदम "0b" स्थिरांक पहचान करने के लिए जीसीसी पैचिंग किया जाएगा लेकिन यह एक overkill :-)

+0

मजाकिया आपने अंतिम भाग का उल्लेख किया है। मैं भी bitset उपयोग कर रहा था <> (स्ट्रिंग (एसटीआर))। To_ulong() – Unknown

+2

मुझे आश्चर्य है कि क्या स्थिति है कि 'द्विआधारी टेम्पलेट' का उपयोग करता है बस सीधा हेक्स स्थिरांक या 'या-इंग' एक साथ के लिए उचित नाम के साथ enums की तुलना में बेहतर बिट्स यदि आप हार्डवेयर या संचार प्रोटोकॉल मॉडलिंग कर रहे हैं? –

+0

असल में जीसीसी 0 बी स्थिरांक का समर्थन करता है। –

3

आप और अधिक गैर प्रकार टेम्पलेट पैरामीटर जोड़ सकते हैं "अनुकरण" करने के लिए अतिरिक्त बिट्स:

// Utility metafunction used by top_bit<N>. 
template <unsigned long long N1, unsigned long long N2> 
struct compare { 
    enum { value = N1 > N2 ? N1 >> 1 : compare<N1 << 1, N2>::value }; 
}; 

// This is hit when N1 grows beyond the size representable 
// in an unsigned long long. It's value is never actually used. 
template<unsigned long long N2> 
struct compare<0, N2> { 
    enum { value = 42 }; 
}; 

// Determine the highest 1-bit in an integer. Returns 0 for N == 0. 
template <unsigned long long N> 
struct top_bit { 
    enum { value = compare<1, N>::value }; 
}; 

template <unsigned long long N1, unsigned long long N2 = 0> 
struct binary { 
    enum { 
     value = 
      (top_bit<binary<N2>::value>::value << 1) * binary<N1>::value + 
      binary<N2>::value 
    }; 
}; 

template <unsigned long long N1> 
struct binary<N1, 0> { 
    enum { value = (N1 % 10) + 2 * binary<N1/10>::value }; 
}; 

template <> 
struct binary<0> { 
    enum { value = 0 } ; 
}; 

आप के रूप में पहले इसका उपयोग कर सकते, जैसे:

binary<1001101>::value 

लेकिन तुम भी निम्न का उपयोग कर सकते बराबर रूपों:

binary<100,1101>::value 
binary<1001,101>::value 
binary<100110,1>::value 

असल में, अतिरिक्त पैरामीटर आप एक और 20 बिट के साथ खेलने के लिए देता है। यदि आवश्यक हो तो आप और भी पैरामीटर जोड़ सकते हैं।

क्योंकि दूसरे नंबर का स्थान मूल्य यह पता लगाने के लिए उपयोग किया जाता है कि बाईं ओर कितनी दूर तक स्थानांतरित करने की आवश्यकता है, दूसरा नंबर 1 से शुरू होना चाहिए। (यह वैसे भी आवश्यक है, इसे शुरू करने के बाद से 0 संख्या को अंडाकार संख्या के रूप में व्याख्या करने का कारण बनता है।)

3
template<unsigned int p,unsigned int i> struct BinaryDigit 
{ 
    enum { value = p*2+i }; 
    typedef BinaryDigit<value,0> O; 
    typedef BinaryDigit<value,1> I; 
}; 
struct Bin 
{ 
    typedef BinaryDigit<0,0> O; 
    typedef BinaryDigit<0,1> I; 
}; 

की अनुमति दे:

बिन :: हे :: मैं :: मैं :: हे :: हे :: मूल्य

भी बहुत कुछ वर्बोज़, लेकिन कोई सीमा नहीं (जब तक आप आकार मारा निश्चित रूप से एक हस्ताक्षरित int के)।

+0

ख़ुशामदी! लेकिन क्या वह हेक्स टाइप करने की बजाय थोड़ा अधिक नहीं होगा? – LiraNuna

+4

स्पष्ट विस्तार 'बिन :: OOOO :: IIOO :: IIIO' जो यकीनन एक बहुत पढ़ने में आसान है, भी होगा। – MSalters

3

तकनीकी तौर पर यह सी है और न ही सी ++ नहीं है, यह एक जीसीसी विशिष्ट एक्सटेंशन है, लेकिन जीसीसी देखा here रूप binary constants अनुमति देता है:

The following statements are identical: 

i =  42; 
i =  0x2a; 
i =  052; 
i = 0b101010; 

आशा है कि मदद करता है। कुछ इंटेल कंपाइलर्स और मुझे यकीन है कि कुछ, जीएनयू एक्सटेंशन में से कुछ को लागू करें। शायद आप भाग्यशाली हैं।

2

एक साधारण #define बहुत अच्छी तरह से काम करता है:

#define HEX__(n) 0x##n##LU 

#define B8__(x) ((x&0x0000000FLU)?1:0)\ 
       +((x&0x000000F0LU)?2:0)\ 
       +((x&0x00000F00LU)?4:0)\ 
       +((x&0x0000F000LU)?8:0)\ 
       +((x&0x000F0000LU)?16:0)\ 
       +((x&0x00F00000LU)?32:0)\ 
       +((x&0x0F000000LU)?64:0)\ 
       +((x&0xF0000000LU)?128:0) 

#define B8(d) ((unsigned char)B8__(HEX__(d))) 
#define B16(dmsb,dlsb) (((unsigned short)B8(dmsb)<<8) + B8(dlsb)) 
#define B32(dmsb,db2,db3,dlsb) (((unsigned long)B8(dmsb)<<24) + ((unsigned long)B8(db2)<<16) + ((unsigned long)B8(db3)<<8) + B8(dlsb)) 

B8(011100111) 
B16(10011011,10011011) 
B32(10011011,10011011,10011011,10011011) 

मेरी आविष्कार, मैं एक लंबे समय पहले एक मंच पर देखा।

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