Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get bits from byte and slice 2 bit pairs

I am new to C++. In Python 3 I can convert the string 'ABC' into selected bits like this and print, whenever a pair of bits are 11:

s = 'ABC'
for i, char in enumerate(s):
    for j in range(4):
        if ord(char) >> 2*j & 0b11 == 3:
            print(i, char, ord(char), j, ord(char) >> 2*j & 0b11)

Which returns:

2 C 67 0 3

How do I do the same in C++; i.e. how do I identify bits 1 and 2 of the character 'C' being 11? I currently have this code:

//#include <string>
//#include <bitset>
#include <iostream>
//using namespace std;
int main(){
  const int bits_in_byte = 8;
  std::string s = "ABC";
  for (std::size_t i = 0; i < s.size(); ++i)
  {
    for (int j = 0; j < 4; ++j) {
      std::cout << i << ' ' << s[i] << ' ' << std::bitset<bits_in_byte>(s[i]) << std::endl;
    }
  }
}

Which returns:

0 A 01000001
0 A 01000001
0 A 01000001
0 A 01000001
1 B 01000010
1 B 01000010
1 B 01000010
1 B 01000010
2 C 01000011
2 C 01000011
2 C 01000011
2 C 01000011
like image 530
tommy.carstensen Avatar asked Mar 10 '23 03:03

tommy.carstensen


1 Answers

You can use the same bit manipulation trick that you used in Python:

for (std::size_t i = 0; i < s.size(); ++i) {
    for (int j = 0; j < 4; ++j) {
        if (((s[i] >> (2*j)) & 3) == 3) {
            std::cout << i << " " << s[i] << " " << (int)s[i] << " " << j << " " << ((s[i] >> 2*j) & 3) << std::endl;
        }
    }
}

You do not need to use ord, because character types of C++ are among the integral types, and are, therefore, freely convertible to integers.

Note the use of parentheses to force the expected order of evaluation.

Demo.

like image 119
Sergey Kalinichenko Avatar answered Mar 21 '23 06:03

Sergey Kalinichenko