Bit Operation macros

Thread Starter

John99407

Joined Jul 12, 2019
77
I do not understand these code lines
C:
/* Bit Operation macros */
#define sbi(b,n) ((b) |= (1<<(n)))          /* Set bit number n in byte b */
#define cbi(b,n) ((b) &= (~(1<<(n))))       /* Clear bit number n in byte b   */
#define fbi(b,n) ((b) ^= (1<<(n)))          /* Flip bit number n in byte b    */
#define rbi(b,n) ((b) & (1<<(n)))           /* Read bit number n in byte b    */
Comments indicate whether a bit is being set, cleared, or toggled in a byte.

Let's assume have a one byte = 1010 1011

I am aware with logic and bitwise operator how to toggle third bit in byte without affecting any other bits ?
 

Papabravo

Joined Feb 24, 2006
22,082
The first three macros are equivalent to an assignment statements where for n=3:
  1. b = b | (1<<3) = b | 0b00001000
  2. b = b & ~(1<<3) = b & 0b11110111
  3. b = b ^ 0b00001000
The last macro is just a simple expression that, for n=3, evaluates to a 0 or nonzero (0x08).
(b & (1<<3)) is the same as (b & 0b00001000)​
What's not to understand?
 

WBahn

Joined Mar 31, 2012
32,823
Let's assume have a one byte = 1010 1011

I am aware with logic and bitwise operator how to toggle third bit in byte without affecting any other bits ?
I think you have a typo/grammar issue. You seem to be making a statement but ending it with a question mark. I'm not sure what you are or are not unsure of or what you are asking. Could you please restate?

Since you focusing on the line that toggles, consider what happens when you perform an XOR between a data bit and a control bit. What is the output relative to the original data bit when the control bit is 0? When it is 1?
 

Thread Starter

John99407

Joined Jul 12, 2019
77
@Papabravo I understand what a logic operation will be for two bytes. I do not understand how to set any bit in the byte without a affecting any other bits

C:
void main() {

  TRISD=0x00;

  PORTD = 0b1010 0101;

  while(1){
    
  }
}
@WBahn I am showing my understanding for logic operator and bit wise operator

Bitwise NOT Reverses each bit For example:-
~11001001 = 00110110

Bitwise AND If either or both bits are 0, the result is 0. For example:-
11001001 & 10011011 = 10001001

Bitwise OR If either or both bits are 1, the result is 1. For example:-
11001001 | 10011011 = 11011011

Bitwise XOR If the two corresponding bits are the same the result is 0. For example:-
11001001 ^ 10011011 = 01010000

Bitwise left shift if x is 00101111 in binary . For example:-

z = x << 1; /* 00101111 << 1 is 01011110 */

Bitwise right shift if x is 00101111 in binary . For example:-

z = x >> 1; /* 00101111 >> 1 is 00010111 */
 

jpanhalt

Joined Jan 18, 2008
11,087
Let's assume have a one byte = 1010 1011

I am aware with logic and bitwise operator how to toggle third bit in byte without affecting any other bits ?
From your first post: Let's assume byte = 1010 1011

If you XOR that repeatedly with 0000 1000 ,
you will toggle bit<3> and leave the rest unchanged on each pass, assuming you XOR with the result of the previous XOR.

Start : 1010 1011
XOR->1010 0011
XOR->1010 1011, and so forth.
 

Papabravo

Joined Feb 24, 2006
22,082
@Papabravo I understand what a logic operation will be for two bytes. I do not understand how to set any bit in the byte without a affecting any other bits

C:
void main() {

  TRISD=0x00;

  PORTD = 0b1010 0101;

  while(1){
  
  }
}
@WBahn I am showing my understanding for logic operator and bit wise operator

Bitwise NOT Reverses each bit For example:-
~11001001 = 00110110

Bitwise AND If either or both bits are 0, the result is 0. For example:-
11001001 & 10011011 = 10001001

Bitwise OR If either or both bits are 1, the result is 1. For example:-
11001001 | 10011011 = 11011011

Bitwise XOR If the two corresponding bits are the same the result is 0. For example:-
11001001 ^ 10011011 = 01010000

Bitwise left shift if x is 00101111 in binary . For example:-

z = x << 1; /* 00101111 << 1 is 01011110 */

Bitwise right shift if x is 00101111 in binary . For example:-

z = x >> 1; /* 00101111 >> 1 is 00010111 */
When you OR a zero with any bit - it remains unchanged. If it was zero it is still zero. If it was a one it remains a one.
When you OR a one with any bit it becomes a one, regardless of it's previous value.
Shifting a single 1 any number of positions to the left creates a byte with a 1 in some position and 7 zeros. If n ≥ 8 then the byte which is created will be identically zero. OR'ing with zero will of course leave the original byte unchanged.
 

Thread Starter

John99407

Joined Jul 12, 2019
77
Can we do bit operation in code, I would be a little easier to understand

C:
void main() {

  TRISD=0x00;

  PORTD = 0b1010 0101;

  while(1){
    
  }
}
providing more details
y = y << n; /* bit position */

Y = `0000 0001

Y = 0000 0001 << 1 = 00000010

Y = 0000 0001 << 2 = 00000100

Y = 0000 0001 << 3 = 00001000

Y = 0000 0001 << 4 = 00010000

Y = 0000 0001 << 5 = 00100000

Y = 0000 0001 << 6 = 01000000

Y = 0000 0001 << 7 = 10000000

set 3rd bit in byte x = 1010 0001
x = 1010 0001
y = 0000 1000
--------------- OR logic
Z = 0000 1000
 

jpanhalt

Joined Jan 18, 2008
11,087
Can we do bit operation in code, I would be a little easier to understand

set 3rd bit in byte x = 1010 0001
x = 1010 0001
y = 0000 1000
--------------- OR logic
Z = 0000 1000
Again, is that a statement or a question?

b'1010 0001' OR'd with b'0000 1000' is NOT b'0000 1000'

It is: b'1010 1001'
 

jpanhalt

Joined Jan 18, 2008
11,087
Did you think about XOR, as pointed out above? I use it routinely to toggle a bit. If you want to ensure a bit is set, you can OR a byte with that bit set or shift as shown in your post #7. In Assembly, you can also use "bsf regA,n" (or its equivalent) or "bcf regA,n"
 

WBahn

Joined Mar 31, 2012
32,823
sorry it's a typo error
b'1010 0001' AND'd with b'0000 1000' is b'0000 1000'
Uhh... b'1010 0001' AND'd with b'0000 1000' is b'0000 0000'.

I am looking help to understand how to set or clear a bit in code
It's been pointed out several times, you just aren't seeing it for what it is.

Let's take a different approach. Instead of seeing what a particular logic operation does for us, let's start with what we want done and see what particular logic operation will do it.

Setting a bit: We have some existing data, D, that can either be a 0 or a 1 and we want to either leave it unchanged if a control bit, C, is a 0 or force it to be a 1 if C is a 1.

What is the truth table for all of the possibilities:

C D Dnew
0 0 0
0 1 1
1 0 1
1 1 1

What logical operation between C and D will produce Dnew?

Clearing a bit: We have some existing data, D, that can either be a 0 or a 1 and we want to either leave it unchanged if a control bit, C, is a 0 or force it to be a 0 if C is a 1.

What is the truth table for all of the possibilities:

C D Dnew
0 0 0
0 1 1
1 0 0
1 1 0

What logical operation between C and D will produce Dnew?

Toggling a bit: We have some existing data, D, that can either be a 0 or a 1 and we want to either leave it unchanged if a control bit, C, is a 0 or force it to be the opposite of what it was if C is a 1.

What is the truth table for all of the possibilities:

C D Dnew
0 0 0
0 1 1
1 0 1
1 1 0

What logical operation between C and D will produce Dnew?
 
Top