Newt_ScAmANdeR's blog

By Newt_ScAmANdeR, 11 months ago, In English

So for starters bit manipulation is doing operations on binary form of a number one could ask why would we need that, under the hood all decimal looking operations occur in binary

There are 6 major operations:

  1. AND(&): This returns true if everything is true.
  2. OR(|): This returns true if anything is true.
  3. XOR(^): This return true if there are odd trues.
  4. NOT(~): This returns the complement (1 if 0 and vise-versa).
  5. RIGHT SHIFT(>>k): Divides(floor) the number by 2, k times, shifts bits by k positions to the right.
  6. LEFT SHIFT(<<K): Multiplies the number by 2, k times, shifts bits by k positions to the left.

Common tasks that one has to do:

  1. SET bit i: x |= (1ULL<<i);
    your doing or with (00000100000) where this thing has bit i set.
  2. CLEAR bit i: x &= ~(1ULL<<i);
    your doing and with (11111011111) where this thing has all bits set but i.
  3. TOGGLE bit i: x ^= (1ULL<<i);
    your doing or with (00000100000) where this thing has bit i set.
  4. CHECK bit i: x&(1ULL<<i)!=0;
    your doing and with (00000100000) where this thing has bit i set and checking if resultant is 0 or not.
    CAUTION USE BELOW AFTER CHECKING NOT 0
  5. ISOLATE LOWEST SET bit: x & (-x);
    This works because -x is stored as (~x+1) in twos complement.
    So if x = 1011000, ~x = 0100111, then -x = (~x+1) = 0101000, x & (~x) = 0001000
  6. CLEAR LOWEST SET bit: x & (x-1);
    This works because when we subtract 1 from a number LSB becomes 0 and 0's to the right become 1
    So if x = 1011000, x-1 = 1010111 , then x&(x-1) = 1010000

Builtin functions in cpp that are a life saver:

  1. __builtin_popcountll(x): gives the number of set bits in x.
  2. __builtin_ctzll(x): gives number of 0's on right of LSB , undefined if x==0.
  3. __builtin_clzll(x): gives number of 0's on the left of MSB , undefined if x==0.
  4. __builtin_parity(x): gives 1 if odd 1's are present else 0.
  • Vote: I like it
  • +12
  • Vote: I do not like it

»
11 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

Auto comment: topic has been updated by Newt_ScAmANdeR (previous revision, new revision, compare).

»
11 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

You probably wrote the reverse thing in Left shift and right shift. I mean you wrote Left shift stuff in Right shift and same for the second one. Just update it. Thank you.

»
11 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

Auto comment: topic has been updated by Newt_ScAmANdeR (previous revision, new revision, compare).

»
11 months ago, hide # |
 
Vote: I like it 0 Vote: I do not like it

Auto comment: topic has been updated by Newt_ScAmANdeR (previous revision, new revision, compare).

»
11 months ago, hide # |
Rev. 2  
Vote: I like it +2 Vote: I do not like it

In ASCII, letters A-Z and a-z differ only in the 5th bit. To convert uppercase to lowercase, set the 5th bit using c | (1<<5) or c | ' '; for example:

char a = 'A' | (1<<5);  // 'A' -> 'a'
char c = 'C' | ' ';      // 'C' -> 'c'

To convert lowercase to uppercase, clear the 5th bit using c & ~(1<<5) or c & '_'; for example:

char D = 'd' & ~(1<<5);  // 'd' -> 'D'
char B = 'b' & '_';      // 'b' -> 'B'

OR sets the bit (lowercase), AND clears it (uppercase), and this works only for letters A-Z and a-z.