C / C ++ में एक बाइट में बिट्स के क्रम को उल्टा करने का सबसे सरल तरीका क्या है?


110

जबकि एक बाइट में बिट ऑर्डर को रिवर्स करने के कई तरीके हैं, मैं उत्सुक हूं कि एक डेवलपर को लागू करने के लिए "सबसे सरल" क्या है। और उलटने से मेरा मतलब है:

1110 -> 0111
0010 -> 0100

यह समान है, लेकिन इस PHP प्रश्न का डुप्लिकेट नहीं है ।

यह इस सी प्रश्न के डुप्लिकेट के समान है, लेकिन नहीं है । यह प्रश्न एक डेवलपर द्वारा लागू करने के लिए सबसे आसान तरीका पूछ रहा है। "बेस्ट एल्गोरिथम" का संबंध मेमोरी और सीपीयू प्रदर्शन से है।


इनलाइन विधानसभा का उपयोग करें। बेहतर, फ़ंक्शन को एक अलग अनुवाद इकाई में डालें। प्रत्येक लक्ष्य मंच के लिए एक विधानसभा भाषा मॉड्यूल है। निर्माण प्रक्रिया को मॉड्यूल चुनने दें।
थॉमस मैथ्यूज

@ और सरलतम कार्यान्वयन
नथन nd

जवाबों:


102

यदि आप एक एकल बाइट के बारे में बात कर रहे हैं, तो एक टेबल-लुकिंग शायद सबसे अच्छा शर्त है, जब तक कि किसी कारण से आपके पास 256 बाइट उपलब्ध न हों।


12
यदि हम किसी ऐसी चीज के बारे में बात कर रहे हैं जो तैयार किए गए समाधान की नकल के बिना लागू करना सरल है, तो लुकअप टेबल बनाने के लिए अभी भी एक और समाधान की आवश्यकता है। (बेशक कोई भी इसे हाथ से कर सकता है, लेकिन यह त्रुटि-प्रवण और समय लेने वाली है ...)
अर्कुक

7
यदि आप palindromes को अनदेखा करते हैं, तो आप सरणी को 256 बाइट्स से कुछ हद तक निचोड़ सकते हैं।
विल्हेमटेल 19

8
@wilhelmtell - आपको यह जानने के लिए एक तालिका की आवश्यकता होगी कि कौन-कौन से हैं।
मार्क रैनसम

6
@wilhelmtell: ठीक है, स्क्रिप्ट लिखने के लिए अभी भी एक और समाधान की आवश्यकता है, जो मेरी बात थी - एक लुकअप तालिका का उपयोग करना सरल है लेकिन बनाने के लिए सरल नहीं है। (एक तैयार लुकअप टेबल को कॉपी करके छोड़कर, लेकिन फिर कोई भी समाधान की नकल कर सकता है।) उदाहरण के लिए, यदि "सरलतम" समाधान को एक माना जाता है जो किसी परीक्षा या साक्षात्कार में कागज पर लिखा जा सकता है, तो मैं नहीं करूंगा। हाथ से एक लुकअप टेबल बनाना शुरू करें और इसे करने के लिए प्रोग्राम बनाएं इसमें पहले से ही एक अलग समाधान शामिल होगा (जो कि यह और तालिका दोनों सहित एक से अधिक सरल होगा)।
अर्कुक

4
@ अर्कुका का मेरा मतलब एक स्क्रिप्ट लिखना है जो पहले 256 बाइट्स की तालिका और उनके रिवर्स मैपिंग को आउटपुट करता है। हां, आप रिवर्स फ़ंक्शन लिखने के लिए वापस आ गए हैं, लेकिन अब आपकी पसंदीदा स्क्रिप्टिंग भाषा में, और यह उतना ही बुरा हो सकता है जितना आप चाहते हैं - आप इसे जल्द से जल्द फेंकने जा रहे हैं और आप इसे एक बार चला चुके हैं। C कोड के रूप में स्क्रिप्ट का आउटपुट है, यहां तक ​​कि unsigned int rtable[] = {0x800, 0x4000, ...};:। फिर स्क्रिप्ट को फेंक दें और भूल जाएं कि आपके पास यह कभी था। समतुल्य सी ++ कोड की तुलना में लिखना बहुत तेज़ है, और यह केवल एक बार ही चलेगा, इसलिए आपको अपने C ++ कोड में O (1) रनटाइम मिलता है।
विल्हेमटेल

227

यह काम करना चाहिए:

unsigned char reverse(unsigned char b) {
   b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
   b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
   b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
   return b;
}

पहले बाएं चार बिट्स को दाएं चार बिट्स के साथ स्वैप किया जाता है। फिर सभी आसन्न जोड़ियों की अदला-बदली की जाती है और फिर सभी आसन्न एकल बिट्स। इससे उलटा क्रम होता है।


26
उचित रूप से छोटा और त्वरित, लेकिन सरल नहीं।
मार्क रैनसम

3
यह दृष्टिकोण सफाई से सामान्यीकरण के लिए बाइट स्वैपिंग करने के लिए भी सामान्यीकृत करता है।
बोजूम

2
सबसे सरल दृष्टिकोण नहीं है, लेकिन मुझे यह पसंद है +1।
नथन

7
हाँ, यह सरल है। यह एक प्रकार का विभाजन है और एल्गोरिथ्म को जीतना है। अति उत्कृष्ट!
kiewic

क्या यह @Arkku द्वारा सुझाई गई विधि से अधिक तेज़ है?
qed

122

मुझे लगता है कि लुकअप टेबल को सबसे सरल तरीकों में से एक होना चाहिए। हालाँकि, आपको पूर्ण लुकअप तालिका की आवश्यकता नहीं है।

//Index 1==0b0001 => 0b1000
//Index 7==0b0111 => 0b1110
//etc
static unsigned char lookup[16] = {
0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe,
0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf, };

uint8_t reverse(uint8_t n) {
   // Reverse the top and bottom nibble then swap them.
   return (lookup[n&0b1111] << 4) | lookup[n>>4];
}

// Detailed breakdown of the math
//  + lookup reverse of bottom nibble
//  |       + grab bottom nibble
//  |       |        + move bottom result into top nibble
//  |       |        |     + combine the bottom and top results 
//  |       |        |     | + lookup reverse of top nibble
//  |       |        |     | |       + grab top nibble
//  V       V        V     V V       V
// (lookup[n&0b1111] << 4) | lookup[n>>4]

यह काफी सरल कोड और नेत्रहीन सत्यापित करने के लिए है।
अंततः यह एक पूर्ण तालिका से भी तेज हो सकता है। बिट एरीट सस्ता है और टेबल आसानी से कैश लाइन पर फिट हो जाता है।


10
यह तालिका समाधान की जटिलता को कम करने का एक शानदार तरीका है। +1
ई.जेम्स

3
अच्छा लगा, लेकिन आपको कैश मिस कर देगा।
जोहान कोटलिंस्की

7
@kotlinski: कैश मिस क्या होगा? मुझे लगता है कि छोटे टेबल संस्करण बड़े की तुलना में अधिक कैश कुशल हो सकते हैं। मेरे Core2 पर एक कैश लाइन 64 बाइट्स चौड़ी है, पूरी टेबल में कई लाइनें होंगी, जबकि छोटी टेबल आसानी से एक सिंगल लाइन को फिट करती है।
deft_code

4
@kotlinski: टेम्पोरल इलाके, कैश हिट या बदलने रणनीतियों के लिए अधिक महत्वपूर्ण है की तुलना में पता इलाके
CFI

6
@ हर्षदीप: टेबल प्रविष्टियों के बाइनरी एनकोडेड इंडेक्स पर विचार करें। सूचकांक b0000 (0) -> b0000 (0x0) उबाऊ; b0001(1) -> b1000(0x8), b0010(2) -> b0100(0x4), b1010(10) -> b0101(0x5)। पैटर्न देखें? यह काफी सरल है कि आप इसे अपने सिर में गणना कर सकते हैं (यदि आप बाइनरी पढ़ सकते हैं, अन्यथा आपको इसे काम करने के लिए कागज की आवश्यकता होगी)। 8 बिट पूर्णांक को उलटने वाली छलांग के लिए 4 बिट भागों को उल्टा करने के बाद उन्हें स्वैप करने के समान है; मैं अनुभव और अंतर्ज्ञान (या जादू) का दावा करता हूं।
deft_code

46

कई समाधानों के लिए बिट ट्विगलिंग हैक देखें । वहां से नकल करना स्पष्ट रूप से लागू करने के लिए सरल है। =)

उदाहरण के लिए (32-बिट CPU पर):

uint8_t b = byte_to_reverse;
b = ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU >> 16;

यदि "सरल रूप से लागू करने के लिए" एक का मतलब है कि एक परीक्षा या नौकरी के साक्षात्कार में एक संदर्भ के बिना किया जा सकता है, तो सबसे सुरक्षित शर्त संभवत: बिट्स की अक्षम प्रतिलिपि है जो एक दूसरे में रिवर्स ऑर्डर में एक दूसरे चर में (पहले से ही अन्य उत्तरों में दिखाया गया है) )।


1
आपके URL से: 32 बिट CPU: b = ((b * 0x0802LU & 0x22110LU) | (b * 0x8020LU & 0x88440LU)) * 0x10101LU: 16;
जोशुआ

1
@ जोशुआ: यह मेरा व्यक्तिगत पसंदीदा भी है। कैविएट (जैसा कि लिंक किए गए पेज पर बताया गया है) यह है कि इसे uint8_t में असाइन या कास्ट करना होगा या ऊपरी बिट्स में कचरा होगा।
अर्कुको

41

चूंकि किसी ने पूरी टेबल लुकअप सॉल्यूशन पोस्ट नहीं किया है, यहाँ मेरा है:

unsigned char reverse_byte(unsigned char x)
{
    static const unsigned char table[] = {
        0x00, 0x80, 0x40, 0xc0, 0x20, 0xa0, 0x60, 0xe0,
        0x10, 0x90, 0x50, 0xd0, 0x30, 0xb0, 0x70, 0xf0,
        0x08, 0x88, 0x48, 0xc8, 0x28, 0xa8, 0x68, 0xe8,
        0x18, 0x98, 0x58, 0xd8, 0x38, 0xb8, 0x78, 0xf8,
        0x04, 0x84, 0x44, 0xc4, 0x24, 0xa4, 0x64, 0xe4,
        0x14, 0x94, 0x54, 0xd4, 0x34, 0xb4, 0x74, 0xf4,
        0x0c, 0x8c, 0x4c, 0xcc, 0x2c, 0xac, 0x6c, 0xec,
        0x1c, 0x9c, 0x5c, 0xdc, 0x3c, 0xbc, 0x7c, 0xfc,
        0x02, 0x82, 0x42, 0xc2, 0x22, 0xa2, 0x62, 0xe2,
        0x12, 0x92, 0x52, 0xd2, 0x32, 0xb2, 0x72, 0xf2,
        0x0a, 0x8a, 0x4a, 0xca, 0x2a, 0xaa, 0x6a, 0xea,
        0x1a, 0x9a, 0x5a, 0xda, 0x3a, 0xba, 0x7a, 0xfa,
        0x06, 0x86, 0x46, 0xc6, 0x26, 0xa6, 0x66, 0xe6,
        0x16, 0x96, 0x56, 0xd6, 0x36, 0xb6, 0x76, 0xf6,
        0x0e, 0x8e, 0x4e, 0xce, 0x2e, 0xae, 0x6e, 0xee,
        0x1e, 0x9e, 0x5e, 0xde, 0x3e, 0xbe, 0x7e, 0xfe,
        0x01, 0x81, 0x41, 0xc1, 0x21, 0xa1, 0x61, 0xe1,
        0x11, 0x91, 0x51, 0xd1, 0x31, 0xb1, 0x71, 0xf1,
        0x09, 0x89, 0x49, 0xc9, 0x29, 0xa9, 0x69, 0xe9,
        0x19, 0x99, 0x59, 0xd9, 0x39, 0xb9, 0x79, 0xf9,
        0x05, 0x85, 0x45, 0xc5, 0x25, 0xa5, 0x65, 0xe5,
        0x15, 0x95, 0x55, 0xd5, 0x35, 0xb5, 0x75, 0xf5,
        0x0d, 0x8d, 0x4d, 0xcd, 0x2d, 0xad, 0x6d, 0xed,
        0x1d, 0x9d, 0x5d, 0xdd, 0x3d, 0xbd, 0x7d, 0xfd,
        0x03, 0x83, 0x43, 0xc3, 0x23, 0xa3, 0x63, 0xe3,
        0x13, 0x93, 0x53, 0xd3, 0x33, 0xb3, 0x73, 0xf3,
        0x0b, 0x8b, 0x4b, 0xcb, 0x2b, 0xab, 0x6b, 0xeb,
        0x1b, 0x9b, 0x5b, 0xdb, 0x3b, 0xbb, 0x7b, 0xfb,
        0x07, 0x87, 0x47, 0xc7, 0x27, 0xa7, 0x67, 0xe7,
        0x17, 0x97, 0x57, 0xd7, 0x37, 0xb7, 0x77, 0xf7,
        0x0f, 0x8f, 0x4f, 0xcf, 0x2f, 0xaf, 0x6f, 0xef,
        0x1f, 0x9f, 0x5f, 0xdf, 0x3f, 0xbf, 0x7f, 0xff,
    };
    return table[x];
}

2
उपयोगी, धन्यवाद। लगता है कि मेरी धीमी शिफ्टिंग विधि एक एम्बेडेड ऐप में प्रदर्शन को सीमित कर रही थी। पीआईसी (रोम कीवर्ड के अतिरिक्त) पर रोम में तालिका रखी।
flend


25
template <typename T>
T reverse(T n, size_t b = sizeof(T) * CHAR_BIT)
{
    assert(b <= std::numeric_limits<T>::digits);

    T rv = 0;

    for (size_t i = 0; i < b; ++i, n >>= 1) {
        rv = (rv << 1) | (n & 0x01);
    }

    return rv;
}

संपादित करें:

वैकल्पिक बिटकॉइन के साथ इसे टेम्पलेट में परिवर्तित किया


@nvl - तय किया गया। मैं एक टेम्पलेट के रूप में निर्माण शुरू कर दिया है, लेकिन नहीं है तो ... भी कई & gt & lt के माध्यम से आधे रास्ते का फैसला किया
andand

अतिरिक्त पेडेनैट्री के लिए, के sizeof(T)*8साथ बदलें sizeof(T)*CHAR_BITS
पिल्ले

6
@andand अतिरिक्त अतिरिक्त लटकन के लिए, बाद में (लगभग 4 साल की पैदल सेना) sizeof(T)*CHAR_BITद्वारा प्रतिस्थापित किया जाता है std::numeric_limits<T>::digits
मोरविन

1
यह होना चाहिए CHAR_BIT, नहीं CHAR_BITS
Xunie

1
यह rv = (rv << 1) होना चाहिए | (n & 0x01);
विग्नेश

16

दो लाइनें:

for(i=0;i<8;i++)
     reversed |= ((original>>i) & 0b1)<<(7-i);

या यदि आपके पास "0b1" भाग के साथ समस्याएँ हैं:

for(i=0;i<8;i++)
     reversed |= ((original>>i) & 1)<<(7-i);

"मूल" बाइट है जिसे आप रिवर्स करना चाहते हैं। "उलटा" परिणाम है, 0 के लिए initialized।


14

हालांकि शायद पोर्टेबल नहीं है, मैं विधानसभा भाषा का उपयोग करेगा।
कई विधानसभा भाषाओं में कैरी फ़्लैग में थोड़ा घुमाने और कैरी फ़्लैग को शब्द (या बाइट) में घुमाने के निर्देश हैं।

एल्गोरिथ्म है:

for each bit in the data type:
  rotate bit into carry flag
  rotate carry flag into destination.
end-for

इसके लिए उच्च स्तरीय भाषा कोड बहुत अधिक जटिल है, क्योंकि सी और सी ++ ले जाने के लिए घूर्णन और ले जाने से घूर्णन का समर्थन नहीं करते हैं। कैरी फ्लैग को मॉडलिंग करना है।

संपादित करें: उदाहरण के लिए विधानसभा भाषा

;  Enter with value to reverse in R0.
;  Assume 8 bits per byte and byte is the native processor type.
   LODI, R2  8       ; Set up the bit counter
Loop:
   RRC, R0           ; Rotate R0 right into the carry bit.
   RLC, R1           ; Rotate R1 left, then append carry bit.
   DJNZ, R2  Loop    ; Decrement R2 and jump if non-zero to "loop"
   LODR, R0  R1      ; Move result into R0.

7
मुझे लगता है कि यह उत्तर सरल के विपरीत है। गैर-पोर्टेबल, असेंबली, और वास्तविक विधानसभा के बजाय छद्म कोड में लिखे जाने के लिए पर्याप्त जटिल है।
deft_code

3
यह काफी सरल है। मैंने इसे छद्म कोड में डाल दिया, क्योंकि असेंबली मेनेमोनिक्स प्रोसेसर की एक नस्ल के लिए विशिष्ट हैं और वहाँ बहुत सारी नस्लें हैं। यदि आप चाहें, तो मैं इसे सरल असेंबली भाषा दिखाने के लिए संपादित कर सकता हूं।
थॉमस मैथ्यूज 16

एक कंपाइलर ऑप्टिमाइज़ेशन एक उपयुक्त असेंबली इंस्ट्रक्शन में सरलता से देख सकता है।
स्पार्कली

12

मुझे लगता है मैं यहाँ देखा है अन्य बिट fiddling एल्गोरिदम की तुलना में निम्नलिखित समाधान सरल है।

unsigned char reverse_byte(char a)
{

  return ((a & 0x1)  << 7) | ((a & 0x2)  << 5) |
         ((a & 0x4)  << 3) | ((a & 0x8)  << 1) |
         ((a & 0x10) >> 1) | ((a & 0x20) >> 3) |
         ((a & 0x40) >> 5) | ((a & 0x80) >> 7);
}

यह बाइट में हर बिट मिलता है, और पहले से आखिरी तक शुरू होता है, तदनुसार इसे बदलता है।

स्पष्टीकरण:

   ((a & 0x1) << 7) //get first bit on the right and shift it into the first left position 
 | ((a & 0x2) << 5) //add it to the second bit and shift it into the second left position
  //and so on

सुंदर! मेरा पसंदीदा अब तक।
निक रामेउ

यह निश्चित रूप से सरल है, लेकिन यह ध्यान दिया जाना चाहिए कि निष्पादन समय ओ (एन) के बजाय ओ (एन) है, जहां एन बिट्स (8, 16, 32, 64, आदि) की संख्या है।
टॉड लेहमैन

10

सबसे सरल तरीका शायद एक लूप में बिट पोजिशन पर चलना है:

unsigned char reverse(unsigned char c) {
   int shift;
   unsigned char result = 0;
   for (shift = 0; shift < CHAR_BIT; shift++) {
      if (c & (0x01 << shift))
         result |= (0x80 >> shift);
   }
   return result;
}

यह CHAR_BIT है, बिना 's'
ljrk

CHAR_BITजब आप char8 बिट्स मानते हैं तो क्यों उपयोग करें ?
चकरली

6

निरंतर, 8-बिट इनपुट के बहुत सीमित मामले के लिए , इस विधि में रन-टाइम पर कोई मेमोरी या CPU खर्च नहीं होता है:

#define MSB2LSB(b) (((b)&1?128:0)|((b)&2?64:0)|((b)&4?32:0)|((b)&8?16:0)|((b)&16?8:0)|((b)&32?4:0)|((b)&64?2:0)|((b)&128?1:0))

मैंने इसका उपयोग ARINC-429 के लिए किया था जहां लेबल का बिट ऑर्डर (एंडियननेस) बाकी शब्दों के विपरीत है। लेबल अक्सर एक स्थिर होता है, और पारंपरिक रूप से ऑक्टल में होता है।

यहां बताया गया है कि मैंने इसे एक स्थिर परिभाषित करने के लिए कैसे इस्तेमाल किया, क्योंकि कल्पना इस लेबल को बड़े-एंडियन 205 ऑक्टल के रूप में परिभाषित करती है।

#define LABEL_HF_COMM MSB2LSB(0205)

और ज्यादा उदाहरण:

assert(0b00000000 == MSB2LSB(0b00000000));
assert(0b10000000 == MSB2LSB(0b00000001));
assert(0b11000000 == MSB2LSB(0b00000011));
assert(0b11100000 == MSB2LSB(0b00000111));
assert(0b11110000 == MSB2LSB(0b00001111));
assert(0b11111000 == MSB2LSB(0b00011111));
assert(0b11111100 == MSB2LSB(0b00111111));
assert(0b11111110 == MSB2LSB(0b01111111));
assert(0b11111111 == MSB2LSB(0b11111111));
assert(0b10101010 == MSB2LSB(0b01010101));

5

आपको इसमें दिलचस्पी हो सकती है std::vector<bool>(जो कि थोड़ा भरा हुआ है) औरstd::bitset

यह अनुरोध के रूप में सबसे सरल होना चाहिए।

#include <iostream>
#include <bitset>
using namespace std;
int main() {
  bitset<8> bs = 5;
  bitset<8> rev;
  for(int ii=0; ii!= bs.size(); ++ii)
    rev[bs.size()-ii-1] = bs[ii];
  cerr << bs << " " << rev << endl;
}

अन्य विकल्प तेज हो सकते हैं।

संपादित करें: मैं आप का उपयोग कर एक समाधान देना है std::vector<bool>

#include <algorithm>
#include <iterator>
#include <iostream>
#include <vector>
using namespace std;
int main() {
  vector<bool> b{0,0,0,0,0,1,0,1};
  reverse(b.begin(), b.end());
  copy(b.begin(), b.end(), ostream_iterator<int>(cerr));
  cerr << endl;
}

दूसरे उदाहरण के लिए c ++ 0x एक्सटेंशन (सरणी को आरंभीकृत करने के लिए {...}) की आवश्यकता होती है । एक bitsetया std::vector<bool>(या boost::dynamic_bitset) का उपयोग करने का लाभ यह है कि आप बाइट्स या शब्दों तक सीमित नहीं हैं, लेकिन बिट्स की एक मनमानी संख्या को उल्टा कर सकते हैं।

HTH


एक फली की तुलना में बिटसेट कितना सरल है? कोड दिखाएं, या यह नहीं है।
विल्हेमटेल 19

एक्टू सहयोगी, मुझे लगता है कि कोड बिटसेट को उल्टा कर देगा, और फिर इसे वापस अपने मूल में बदल देगा। बदलें ii! = आकार (); करने के लिए ii <आकार () / 2; और यह एक बेहतर काम करेगा =)
विक्टर सेहर

(@ viktor-sehr no, it will, Rev, bs से अलग है)। वैसे भी मुझे खुद जवाब पसंद नहीं है: मुझे लगता है कि यह एक ऐसा मामला है जहां बाइनरी अंकगणितीय और शिफ्ट ऑपरेटर बेहतर अनुकूल हैं। यह अभी भी समझने में सबसे सरल है।
बाओल

कैसे के बारे में std::vector<bool> b = { ... }; std::vector<bool> rb ( b.rbegin(), b.rend()); - सीधे पुनरावृत्तियों का उपयोग कर?
MSalters 21

@MSalters मुझे इसकी अपरिहार्यता पसंद है।
baol

5

बिट्स को उल्टा करने के कई तरीके हैं जो इस बात पर निर्भर करता है कि आप "सबसे सरल तरीका" हैं।


रोटेशन से उलटा

संभवतः सबसे तार्किक, पहले बिट पर मुखौटा लागू करते समय बाइट को घुमाने में शामिल हैं (n & 1):

unsigned char reverse_bits(unsigned char b)
{
    unsigned char   r = 0;
    unsigned        byte_len = 8;

    while (byte_len--) {
        r = (r << 1) | (b & 1);
        b >>= 1;
    }
    return r;
}

1) एक अहस्ताक्षरित चार की लंबाई 1 बाइट है, जो 8 बिट के बराबर है, इसका मतलब है कि हम प्रत्येक बिट को स्कैन करेंगे while (byte_len--)

2) हम पहली बार जाँचते हैं कि अगर b दायीं ओर थोड़ा सा है (b & 1); यदि ऐसा है तो हम r के साथ बिट 1 सेट करते हैं |और इसे r से 2 से गुणा करके केवल 1 बिट को बाईं ओर ले जाते हैं(r << 1)

3) फिर हम अपने अहस्ताक्षरित चार बी b >>=1को चर बी के चरम दाईं ओर स्थित बिट को मिटाने के लिए विभाजित करते हैं । एक अनुस्मारक के रूप में, बी >> = 1; b / = 2 के बराबर है;


एक पंक्ति में उल्टा

इस समाधान को प्रोग्रामिंग हैक्स अनुभाग में रिच श्रोएपेल को जिम्मेदार ठहराया गया है

unsigned char reverse_bits3(unsigned char b)
{
    return (b * 0x0202020202ULL & 0x010884422010ULL) % 0x3ff;
}

1) गुणा ऑपरेशन (b * 0x0202020202ULL) 8-बिट बाइट पैटर्न की पांच अलग-अलग प्रतियों को 64-बिट मान में पंखे से बाहर करने के लिए बनाता है।

2) AND ऑपरेशन (& 0x010884422010ULL) उन बिट्स का चयन करता है जो प्रत्येक 10-बिट समूहों के सापेक्ष सही (उलट) स्थिति में होते हैं।

3) एक साथ गुणा और AND ऑपरेशन बिट को मूल बाइट से कॉपी करते हैं ताकि वे प्रत्येक 10-बिट सेट में से केवल एक में दिखाई दें। मूल बाइट से बिट्स का उलटा स्थान किसी भी 10-बिट सेट के भीतर उनके सापेक्ष पदों के साथ मेल खाता है।

4) अंतिम चरण (% 0x3ff), जिसमें 2 ^ 10 - 1 द्वारा मापांक विभाजन शामिल है, 10 बिट्स के प्रत्येक सेट (0-9, 10-19, 20-29, ...) से एक साथ विलय करने का प्रभाव है। 64-बिट मूल्य में। वे ओवरलैप नहीं करते हैं, इसलिए मापांक डिवीजन में अंतर्निहित अतिरिक्त कदम OR ऑपरेशन की तरह व्यवहार करते हैं।


फूट डालो और जीतो हल

unsigned char reverse(unsigned char b) {
   b = (b & 0xF0) >> 4 | (b & 0x0F) << 4;
   b = (b & 0xCC) >> 2 | (b & 0x33) << 2;
   b = (b & 0xAA) >> 1 | (b & 0x55) << 1;
   return b;
}

यह सबसे उत्तोलित उत्तर है और कुछ स्पष्टीकरणों के बावजूद, मुझे लगता है कि ज्यादातर लोगों के लिए व्हाट्स 0xF0, 0xCC, 0xAA, 0x0F, 0x33 और 0x55 का वास्तविक अर्थ निकालना कठिन है।

यह '0b' का लाभ नहीं लेता है जो कि GCC एक्सटेंशन है और C ++ 14 मानक के बाद से शामिल है, दिसंबर 2014 में रिलीज़ हुआ, इसलिए इस उत्तर के बाद अप्रैल 2010 से डेटिंग

पूर्णांक स्थिरांक को द्विआधारी स्थिरांक के रूप में लिखा जा सकता है, जिसमें '0 बी' या '0 बी' द्वारा उपसर्ग '0' और '1' अंकों के अनुक्रम होते हैं। यह उन वातावरणों में विशेष रूप से उपयोगी है जो बिट स्तर (जैसे माइक्रोकंट्रोलर्स) पर बहुत काम करते हैं।

कृपया इस समाधान को याद रखने और समझने के लिए नीचे दिए गए कोड स्निपेट की जांच करें, जहां हम आधे से आधे में आगे बढ़ते हैं:

unsigned char reverse(unsigned char b) {
   b = (b & 0b11110000) >> 4 | (b & 0b00001111) << 4;
   b = (b & 0b11001100) >> 2 | (b & 0b00110011) << 2;
   b = (b & 0b10101010) >> 1 | (b & 0b01010101) << 1;
   return b;
}

NB: ऐसा >> 4इसलिए है क्योंकि 1 बाइट में 8 बिट्स होते हैं, जो एक अहस्ताक्षरित चार है इसलिए हम दूसरे हाफ को लेना चाहते हैं, और इसी तरह।

हम इस समाधान को केवल दो अतिरिक्त लाइनों के साथ 4 बाइट्स पर लागू कर सकते हैं और उसी तर्क का पालन कर सकते हैं। चूंकि दोनों मुखौटा एक दूसरे के पूरक हैं इसलिए हम बिट्स को स्विच करने और कुछ स्याही को बचाने के लिए भी ~ का उपयोग कर सकते हैं:

uint32_t reverse_integer_bits(uint32_t b) {
   uint32_t mask = 0b11111111111111110000000000000000;
   b = (b & mask) >> 16 | (b & ~mask) << 16;
   mask = 0b11111111000000001111111100000000;
   b = (b & mask) >> 8 | (b & ~mask) << 8;
   mask = 0b11110000111100001111000011110000;
   b = (b & mask) >> 4 | (b & ~mask) << 4;
   mask = 0b11001100110011001100110011001100;
   b = (b & mask) >> 2 | (b & ~mask) << 2;
   mask = 0b10101010101010101010101010101010;
   b = (b & mask) >> 1 | (b & ~mask) << 1;
   return b;
}

[C ++ केवल] किसी भी अनसाइन्ड (टेम्प्लेट) को उल्टा करें

उपरोक्त तर्क को एक लूप के साथ संक्षेपित किया जा सकता है जो किसी भी प्रकार के अहस्ताक्षरित पर काम करेगा:

template <class T>
T reverse_bits(T n) {
    short bits = sizeof(n) * 8; 
    T mask = ~T(0); // equivalent to uint32_t mask = 0b11111111111111111111111111111111;

    while (bits >>= 1) {
        mask ^= mask << (bits); // will convert mask to 0b00000000000000001111111111111111;
        n = (n & ~mask) >> bits | (n & mask) << bits; // divide and conquer
    }

    return n;
}

उपरोक्त फ़ंक्शन को शामिल करने के साथ इसे स्वयं आज़माएँ:

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>

template <class T>
void print_binary(T n)
{   T mask = 1ULL << ((sizeof(n) * 8) - 1);  // will set the most significant bit
    for(; mask != 0; mask >>= 1) putchar('0' | !!(n & mask));
    putchar('\n');
}

int main() {
    uint32_t n = 12;
    print_binary(n);
    n = reverse_bits(n); 
    print_binary(n);
    unsigned char c = 'a';
    print_binary(c);
    c = reverse_bits(c);
    print_binary(c);
    uint16_t s = 12;
    print_binary(s);
    s = reverse_bits(s);
    print_binary(s);
    uint64_t l = 12;
    print_binary(l);
    l = reverse_bits(l);
    print_binary(l);
    return 0;
}

एएसएम अस्थिर के साथ उल्टा

अंतिम लेकिन कम से कम, यदि सबसे सरल का मतलब कम रेखाएं हैं, तो इनलाइन असेंबली का प्रयास क्यों न करें?

-masm=intelसंकलन करते समय आप कोड स्निपेट के नीचे परीक्षण कर सकते हैं :

unsigned char reverse_bits(unsigned char c) {
    __asm__ __volatile__ (R"(
        mov cx, 8       
    daloop:                   
        ror di          
        adc ax, ax      
        dec cx          
        jnz short daloop  
    ;)");
}

स्पष्टीकरण पंक्ति द्वारा पंक्ति:

        mov cx, 8       ; we will reverse the 8 bits contained in one byte
    daloop:             ; while loop
        shr di          ; Shift Register `di` (containing value of the first argument of callee function) to the Right
        rcl ax          ; Rotate Carry Left: rotate ax left and add the carry from shr di, the carry is equal to 1 if one bit was "lost" from previous operation 
        dec cl          ; Decrement cx
        jnz short daloop; Jump if cx register is Not equal to Zero, else end loop and return value contained in ax register

3

टेबल लुकअप या

uint8_t rev_byte(uint8_t x) {
    uint8_t y;
    uint8_t m = 1;
    while (m) {
       y >>= 1;
       if (m&x) {
          y |= 0x80;
       }
       m <<=1;
    }
    return y;
}

संपादित करें

अन्य समाधानों के लिए यहां देखें जो आपके लिए बेहतर काम कर सकते हैं


3

एक धीमी लेकिन सरल कार्यान्वयन:

static int swap_bit(unsigned char unit)
{
    /*
     * swap bit[7] and bit[0]
     */
    unit = (((((unit & 0x80) >> 7) ^ (unit & 0x01)) << 7) | (unit & 0x7f));
    unit = (((((unit & 0x80) >> 7) ^ (unit & 0x01))) | (unit & 0xfe));
    unit = (((((unit & 0x80) >> 7) ^ (unit & 0x01)) << 7) | (unit & 0x7f));

    /*
     * swap bit[6] and bit[1]
     */
    unit = (((((unit & 0x40) >> 5) ^ (unit & 0x02)) << 5) | (unit & 0xbf));
    unit = (((((unit & 0x40) >> 5) ^ (unit & 0x02))) | (unit & 0xfd));
    unit = (((((unit & 0x40) >> 5) ^ (unit & 0x02)) << 5) | (unit & 0xbf));

    /*
     * swap bit[5] and bit[2]
     */
    unit = (((((unit & 0x20) >> 3) ^ (unit & 0x04)) << 3) | (unit & 0xdf));
    unit = (((((unit & 0x20) >> 3) ^ (unit & 0x04))) | (unit & 0xfb));
    unit = (((((unit & 0x20) >> 3) ^ (unit & 0x04)) << 3) | (unit & 0xdf));

    /*
     * swap bit[4] and bit[3]
     */
    unit = (((((unit & 0x10) >> 1) ^ (unit & 0x08)) << 1) | (unit & 0xef));
    unit = (((((unit & 0x10) >> 1) ^ (unit & 0x08))) | (unit & 0xf7));
    unit = (((((unit & 0x10) >> 1) ^ (unit & 0x08)) << 1) | (unit & 0xef));

    return unit;
}

3

क्या यह तेज समाधान हो सकता है?

int byte_to_be_reversed = 
    ((byte_to_be_reversed>>7)&0x01)|((byte_to_be_reversed>>5)&0x02)|      
    ((byte_to_be_reversed>>3)&0x04)|((byte_to_be_reversed>>1)&0x08)| 
    ((byte_to_be_reversed<<7)&0x80)|((byte_to_be_reversed<<5)&0x40)|
    ((byte_to_be_reversed<<3)&0x20)|((byte_to_be_reversed<<1)&0x10);

एक पाश के लिए उपयोग करने की हलचल से छुटकारा मिल जाता है! लेकिन विशेषज्ञ कृपया मुझे बताएं कि क्या यह कुशल और तेज है?


इसका निष्पादन समय ओ (एन) के बजाय ओ (एन) है, जहां एन बिट्स (8, 16, 32, 64, आदि) की संख्या है। O (log) n) समय में निष्पादित होने वाले उत्तरों के लिए अन्यत्र देखें।
टॉड लेहमन

2

किसी भी एल्गोरिथम समाधान को लागू करने से पहले, जो भी सीपीयू आर्किटेक्चर आप उपयोग कर रहे हैं, उसके लिए विधानसभा भाषा की जांच करें। आपकी वास्तुकला में ऐसे निर्देश शामिल हो सकते हैं जो इस तरह के बिटवाइज़ जोड़तोड़ को संभालते हैं (और एक विधानसभा निर्देश से आसान क्या हो सकता है?)।

यदि ऐसा कोई निर्देश उपलब्ध नहीं है, तो मैं लुकअप टेबल मार्ग के साथ जाने का सुझाव दूंगा। आप के लिए तालिका तैयार करने के लिए आप एक स्क्रिप्ट / प्रोग्राम लिख सकते हैं, और लुकअप ऑपरेशन यहाँ किसी भी बिट-रिवर्सिंग एल्गोरिदम की तुलना में तेज़ होगा (लुकअप टेबल को कहीं स्टोर करने की लागत पर)।


2

यह सरल कार्य इनपुट बाइट में प्रत्येक बिट का परीक्षण करने और इसे शिफ्टिंग आउटपुट में स्थानांतरित करने के लिए मास्क का उपयोग करता है:

char Reverse_Bits(char input)
{    
    char output = 0;

    for (unsigned char mask = 1; mask > 0; mask <<= 1)
    {
        output <<= 1;

        if (input & mask)
            output |= 1;
    }

    return output;
}

मास्क को अहस्ताक्षरित किया जाना चाहिए।
luci88filter

1

यह एक प्रदान की गई BobStein-VisiBone पर आधारित है

#define reverse_1byte(b)    ( ((uint8_t)b & 0b00000001) ? 0b10000000 : 0 ) | \
                            ( ((uint8_t)b & 0b00000010) ? 0b01000000 : 0 ) | \
                            ( ((uint8_t)b & 0b00000100) ? 0b00100000 : 0 ) | \
                            ( ((uint8_t)b & 0b00001000) ? 0b00010000 : 0 ) | \
                            ( ((uint8_t)b & 0b00010000) ? 0b00001000 : 0 ) | \
                            ( ((uint8_t)b & 0b00100000) ? 0b00000100 : 0 ) | \
                            ( ((uint8_t)b & 0b01000000) ? 0b00000010 : 0 ) | \
                            ( ((uint8_t)b & 0b10000000) ? 0b00000001 : 0 ) 

मैं वास्तव में इसे बहुत पसंद करता हूं क्योंकि कंपाइलर स्वचालित रूप से आपके लिए काम संभालता है, इस प्रकार आगे संसाधनों की आवश्यकता नहीं होती है।

इसे 16-बिट्स तक बढ़ाया जा सकता है ...

#define reverse_2byte(b)    ( ((uint16_t)b & 0b0000000000000001) ? 0b1000000000000000 : 0 ) | \
                            ( ((uint16_t)b & 0b0000000000000010) ? 0b0100000000000000 : 0 ) | \
                            ( ((uint16_t)b & 0b0000000000000100) ? 0b0010000000000000 : 0 ) | \
                            ( ((uint16_t)b & 0b0000000000001000) ? 0b0001000000000000 : 0 ) | \
                            ( ((uint16_t)b & 0b0000000000010000) ? 0b0000100000000000 : 0 ) | \
                            ( ((uint16_t)b & 0b0000000000100000) ? 0b0000010000000000 : 0 ) | \
                            ( ((uint16_t)b & 0b0000000001000000) ? 0b0000001000000000 : 0 ) | \
                            ( ((uint16_t)b & 0b0000000010000000) ? 0b0000000100000000 : 0 ) | \
                            ( ((uint16_t)b & 0b0000000100000000) ? 0b0000000010000000 : 0 ) | \
                            ( ((uint16_t)b & 0b0000001000000000) ? 0b0000000001000000 : 0 ) | \
                            ( ((uint16_t)b & 0b0000010000000000) ? 0b0000000000100000 : 0 ) | \
                            ( ((uint16_t)b & 0b0000100000000000) ? 0b0000000000010000 : 0 ) | \
                            ( ((uint16_t)b & 0b0001000000000000) ? 0b0000000000001000 : 0 ) | \
                            ( ((uint16_t)b & 0b0010000000000000) ? 0b0000000000000100 : 0 ) | \
                            ( ((uint16_t)b & 0b0100000000000000) ? 0b0000000000000010 : 0 ) | \
                            ( ((uint16_t)b & 0b1000000000000000) ? 0b0000000000000001 : 0 ) 

bअगर यह एक ही संख्या की तुलना में अधिक जटिल अभिव्यक्ति है, और संभवतया मैक्रो का नाम बदलकर REVERSE_BYTEसंकेत के रूप में मैं कोष्ठक में रखूंगा, तो संभवत: एक संकेत के रूप में मैक्रो का नाम बदलें जिसे आप शायद अधिक जटिल (रनटाइम) अभिव्यक्ति नहीं करना चाहते हैं। या इसे एक इनलाइन फ़ंक्शन बनाते हैं। (लेकिन कुल मिलाकर मुझे यह इतना सरल लगता है कि आप इसे बहुत कम त्रुटि के साथ आसानी से मेमोरी से कर सकते हैं।)
अरकुक्कू

1

यह मानते हुए कि आपका संकलक लंबे समय तक अप्रयुक्त है :

unsigned char reverse(unsigned char b) {
  return (b * 0x0202020202ULL & 0x010884422010ULL) % 1023;
}

यहां खोजा गया


1

यदि आप छोटे माइक्रोकंट्रोलर का उपयोग कर रहे हैं और छोटे पदचिह्न के साथ उच्च गति समाधान की आवश्यकता है, तो यह समाधान हो सकता है। सी प्रोजेक्ट के लिए इसका उपयोग करना संभव है, लेकिन आपको इस फाइल को असेंबलर फाइल * .स्म के रूप में अपने सी प्रोजेक्ट में जोड़ना होगा। निर्देश: सी परियोजना में यह घोषणा जोड़ें:

extern uint8_t byte_mirror(uint8_t);

इस फ़ंक्शन को C से कॉल करें

byteOutput= byte_mirror(byteInput);

यह कोड है, यह केवल 8051 कोर के लिए उपयुक्त है। CPU रजिस्टर में r0 byteInput का डेटा होता है । कोड घुमाएँ सही r0 क्रॉस कैरी और फिर रोटेट लेफ्ट को r1 तक ले जाएँ । इस प्रक्रिया को 8 बार दोहराएं, हर बिट के लिए। तब रजिस्टर r1 को बाइटऑटपुट के रूप में c फंक्शन में लौटा दिया जाता है। 8051 में कोर केवल एक्यूमुलेटर को घुमाने के लिए पॉसिबल है

NAME     BYTE_MIRROR
RSEG     RCODE
PUBLIC   byte_mirror              //8051 core        

byte_mirror
    mov r3,#8;
loop:   
    mov a,r0;
    rrc a;
    mov r0,a;    
    mov a,r1;
    rlc a;   
    mov r1,a;
    djnz r3,loop
    mov r0,a
    ret

PROS: यह छोटा पदचिह्न है, यह उच्च गति है CONS: यह पुन: प्रयोज्य कोड नहीं है, यह केवल 8051 के लिए है

011101101-> कैरी

101101110 <-carry


हालांकि यह कोड प्रश्न का उत्तर दे सकता है, लेकिन कुछ संदर्भों को शामिल करना बेहतर होगा, यह बताते हुए कि यह कैसे काम करता है और इसका उपयोग कब करना है। कोड-केवल उत्तर लंबे समय में उपयोगी नहीं हैं।
fNek

0
  xor ax,ax
  xor bx,bx
  mov cx,8
  mov al,original_byte!
cycle:   shr al,1
  jnc not_inc
  inc bl
not_inc: test cx,cx
  jz,end_cycle
  shl bl,1
  loop cycle
end_cycle:

उल्टे बाइट को ब्ल रजिस्टर पर रखा जाएगा


3
एक अन्य संदर्भ में जो एक उचित जवाब हो सकता है, लेकिन सवाल सी या सी ++ के बारे में था, न कि asm ...
jadsq

0
typedef struct
{
    uint8_t b0:1;
    uint8_t b1:1;
    uint8_t b2:1;
    uint8_t b3:1;
    uint8_t b4:1;
    uint8_t b5:1;
    uint8_t b6:1;
    uint8_t b7:1;
} bits_t;

uint8_t reverse_bits(uint8_t src)
{
    uint8_t dst = 0x0;
    bits_t *src_bits = (bits_t *)&src;
    bits_t *dst_bits = (bits_t *)&dst;

    dst_bits->b0 = src_bits->b7;
    dst_bits->b1 = src_bits->b6;
    dst_bits->b2 = src_bits->b5;
    dst_bits->b3 = src_bits->b4;
    dst_bits->b4 = src_bits->b3;
    dst_bits->b5 = src_bits->b2;
    dst_bits->b6 = src_bits->b1;
    dst_bits->b7 = src_bits->b0;

    return dst;
}

एक शैलीगत नोट के रूप में, मुझे uint8_t1-बिट फ़ील्ड के लिए उपयोग थोड़ा बदसूरत लगता है, क्योंकि यह पहली बार लगता है कि यह 8 बिट ले जाएगा, लेकिन फिर लाइन के अंत में इसे केवल एक बिट के रूप में परिभाषित करता है। मैं unsigned b0:1आदि का उपयोग
करूँगा

0
#include <stdio.h>
#include <stdlib.h>

int main()
{
    int i;
    unsigned char rev = 0x70 ; // 0b01110000
    unsigned char tmp = 0;

    for(i=0;i<8;i++)
    {
    tmp |= ( ((rev & (1<<i))?1:0) << (7-i));
    }
    rev = tmp;

    printf("%x", rev);       //0b00001110 binary value of given number
    return 0;
}

कृपया कुछ स्पष्टीकरण जोड़ें।
zcui93

0

मुझे लगता है कि यह काफी सरल है

uint8_t reverse(uint8_t a)
{
  unsigned w = ((a << 7) & 0x0880) | ((a << 5) & 0x0440) | ((a << 3) & 0x0220) | ((a << 1) & 0x0110);
  return static_cast<uint8_t>(w | (w>>8));
}

या

uint8_t reverse(uint8_t a)
{
  unsigned w = ((a & 0x11) << 7) | ((a & 0x22) << 5) | ((a & 0x44) << 3) | ((a & 0x88) << 1);
  return static_cast<uint8_t>(w | (w>>8));
}

0
unsigned char c ; // the original
unsigned char u = // the reversed
c>>7&0b00000001 |
c<<7&0b10000000 |
c>>5&0b00000010 |
c<<5&0b01000000 |
c>>3&0b00000100 |
c<<3&0b00100000 |
c>>1&0b00001000 |
c<<1&0b00010000 ;

Explanation: exchanged bits as per the arrows below.
01234567
<------>
#<---->#
##<-->##
###<>###

0

मैं अपने समाधान में चिप लगाऊंगा, क्योंकि मुझे अब तक जवाब में ऐसा कुछ नहीं मिला। हो सकता है कि यह थोड़ा अधिक हो, लेकिन यह std::index_sequenceसंकलन समय में C ++ 14 का उपयोग करके लुकअप तालिका उत्पन्न करता है।

#include <array>
#include <utility>

constexpr unsigned long reverse(uint8_t value) {
    uint8_t result = 0;
    for (std::size_t i = 0, j = 7; i < 8; ++i, --j) {
        result |= ((value & (1 << j)) >> j) << i;
    }
    return result;
}

template<size_t... I>
constexpr auto make_lookup_table(std::index_sequence<I...>)
{
    return std::array<uint8_t, sizeof...(I)>{reverse(I)...};   
}

template<typename Indices = std::make_index_sequence<256>>
constexpr auto bit_reverse_lookup_table()
{
    return make_lookup_table(Indices{});
}

constexpr auto lookup = bit_reverse_lookup_table();

int main(int argc)
{
    return lookup[argc];
}

https://godbolt.org/z/cSuWhF


0

यहाँ एक सरल और पठनीय समाधान है, सभी अनुरूप प्लेटफार्मों के लिए पोर्टेबल, जिनमें शामिल हैं sizeof(char) == sizeof(int):

#include <limits.h>

unsigned char reverse(unsigned char c) {
    int shift;
    unsigned char result = 0;

    for (shift = 0; shift < CHAR_BIT; shift++) {
        result <<= 1;
        result |= c & 1;
        c >>= 1;
    }
    return result;
}

0

मुझे पता है कि यह प्रश्न दिनांकित है, लेकिन मुझे अभी भी लगता है कि विषय कुछ उद्देश्यों के लिए प्रासंगिक है, और यहां एक संस्करण है जो बहुत अच्छी तरह से काम करता है और पठनीय है। मैं यह नहीं कह सकता कि यह सबसे तेज या सबसे कुशल है, लेकिन इसे सबसे साफ में से एक होना चाहिए। मैंने बिट पैटर्न को आसानी से प्रदर्शित करने के लिए एक सहायक फ़ंक्शन भी शामिल किया है। यह फ़ंक्शन अपने स्वयं के बिट मैनिप्युलेटर को लिखने के बजाय कुछ मानक पुस्तकालय कार्यों का उपयोग करता है।

#include <algorithm>
#include <bitset>
#include <exception>
#include <iostream>
#include <limits>
#include <string>

// helper lambda function template
template<typename T>
auto getBits = [](T value) {
    return std::bitset<sizeof(T) * CHAR_BIT>{value};
};

// Function template to flip the bits
// This will work on integral types such as int, unsigned int,
// std::uint8_t, 16_t etc. I did not test this with floating
// point types. I chose to use the `bitset` here to convert
// from T to string as I find it easier to use than some of the
// string to type or type to string conversion functions,
// especially when the bitset has a function to return a string. 
template<typename T>
T reverseBits(T& value) {
    static constexpr std::uint16_t bit_count = sizeof(T) * CHAR_BIT;

    // Do not use the helper function in this function!
    auto bits = std::bitset<bit_count>{value};
    auto str = bits.to_string();
    std::reverse(str.begin(), str.end());
    bits = std::bitset<bit_count>(str);
    return static_cast<T>( bits.to_ullong() );
}

// main program
int main() {
    try {
        std::uint8_t value = 0xE0; // 1110 0000;
        std::cout << +value << '\n'; // don't forget to promote unsigned char
        // Here is where I use the helper function to display the bit pattern
        auto bits = getBits<std::uint8_t>(value);
        std::cout << bits.to_string() << '\n';

        value = reverseBits(value);
        std::cout << +value << '\n'; // + for integer promotion

        // using helper function again...
        bits = getBits<std::uint8_t>(value);
        std::cout << bits.to_string() << '\n';

    } catch(const std::exception& e) {  
        std::cerr << e.what();
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

और यह निम्न आउटपुट देता है।

224
11100000
7
00000111

0

इसने मुझे 8x8 डॉट मैट्रिक्स सेट ऐरे के साथ मदद की।

uint8_t mirror_bits(uint8_t var)
{
    uint8_t temp = 0;
    if ((var & 0x01))temp |= 0x80;
    if ((var & 0x02))temp |= 0x40;
    if ((var & 0x04))temp |= 0x20;
    if ((var & 0x08))temp |= 0x10;

    if ((var & 0x10))temp |= 0x08;
    if ((var & 0x20))temp |= 0x04;
    if ((var & 0x40))temp |= 0x02;
    if ((var & 0x80))temp |= 0x01;

    return temp;
}

1
यह फ़ंक्शन वास्तव में काम नहीं करता है, 0b11001111 का रिवर्स 0b11110011 होना चाहिए, लेकिन इस फ़ंक्शन के साथ विफल हो जाता है। एक ही परीक्षण विधि यहां सूचीबद्ध कई अन्य कार्यों के लिए काम करती है।
दान

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