## Split from: [TUT] [C] Bit manipulation (AKA "Programming 101")

9 posts / 0 new
Author
Message

From the OP...

abcminiuser wrote:
To see if a bit is set or clear just requires the AND operator, but with no assignment. To see if bit 7 is set in the variable foo:
`if(foo & 0x80) { }`

The condition will be zero if the bit is clear, and the condition will be non-zero if the bit is set. NOTE! The condition will be NON-ZERO when the bit is set. But the condition will not NECESSARILY BE ONE.

I'm having difficulty with this bit of code (no pun intended).  I get the truth tables and most everything else where there is an assignment being made.  What is making the "(foo & 0x80)" evaluate to a 1 or a 0?  My entire understanding of bitwise operators is based on two bytes evaluating to a single byte.  In the above code snippet two bytes are evaluating to a bit (boolean?).  What if you had something instead like "(foo & 0x81)"?  Would both bits need to evaluate to 1 in order for the if() statement to execute?

Last Edited: Thu. Jul 14, 2016 - 12:00 PM
Total votes: 0

In the example 0x80 has bit 7 set to '1' and the rest are set to '0'.  Foo is anded to 0x80 and if foo has bit 7 set to '1' then the result is 1...it's a bit test of bit 7

chipz wrote:
What if you had something instead like "(foo & 0x81)"? Would both bits need to evaluate to 1 in order for the if() statement to execute?

EDIT:

See post below this one....

Jim

EDIT:

If you are using Studio, you can test all of this in the simulator quite nicely.

If you want a career with a known path - become an undertaker. Dead people don't sue! - Kartman

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB user

Last Edited: Wed. Jul 13, 2016 - 10:32 PM
Total votes: 0

True is a non zero value and False is a zero value. From your AND operation, we have four possible result:
0
0x80
0x01
0x81

Which ones are true or false based on my first comment?

Total votes: 0

My difficulty isn't in determining whether a number is true or false, rather how the number was determined in the first place.

Using binary for simplicity and clarity:

0b10000000  (lets use this value for the foo value)

& 0b10000001  (0x81)

0b10000000   (result)

So the if statement is executed, right?  Even though the least significant digit evaluates to false?  It's an AND operator (bitwise), yet one of the digits evaluates to false (0x01)... which seems like 0x81 should evaluate to false because it is in essence, an implied logical OR.  Yes?  I hope that explains what was going through my head.

So to be clear, it only takes one of the bits expressed in the second operand (say, 0xD4) to evaluate true returning a non-zero byte result.  Therefore the if() executes.  Do I have it right?

Total votes: 0

You are mixing up true/false with numeric value.

In C, 0, (that is, 0x00 or 0x0000 or whatever) is taken to be false.

ANYTHING else is taken as true.

So  0x80 combined using a bitwise-AND with 0x81 = 0x80 and will be TRUE.

On the other hand, 0x80 combined using a logical AND with 0x81 is also TRUE because both 0x80 and 0x81 are logically TRUE.

You are also confusing yourself when you talk about "digits".  in the expression 0b10000000, there are 8 BITS, not 8 digits.

Jim

Jim Wagner Oregon Research Electronics, Consulting Div. Tangent, OR, USA http://www.orelectronics.net

Last Edited: Thu. Jul 14, 2016 - 02:54 AM
Total votes: 0

Not quite, if ANY of the bits of the result of the AND are non-zero, then the result is true. The ONLY value that represents false is 0x00.

David (aka frog_jr)

Total votes: 0

Think of some byte values that have either bit 0 and/or bit 7 set (11111111, 10101010, 01010101, etc for examples) and think of some byte values that have neither bit 7 nor bit 0 set (01111110, 01010110, 00010000).

Now try them out AND with the 0x81 (10000001) mask value to pick out the state of bits 7 and 0:

11111111

&10000001

========

10000001 - this is non-0 so it will be taken as true

10101010

&10000001

========

10000000 - this is non-0 so will be taken as true

01010101

&10000001

========

00000001- this is non-0 so will be taken as true

01111110

&10000001

========

00000000 - result 0 - so false

01010110

&10000001

========

00000000 - result 0 - so false

00010000

&10000001

========

00000000 - result 0 - so false

As you can see from this the 6 bits in the middle (the 6 0's in the middle of 0x81) are completely ignored and have no effect on the result. Only bits 7 and 0 are significant. If either or both is 1 then the overall result is non-0 (true). If both are 0 then the overall result is 0x00 (false).

So an AND mask lets you pick out the state of one or more bits and used in the form "if (input & mask) ..." the result will be true and execute the conditional if any of the mask pattern bit positions is/are 1 in the input.

Total votes: 0

frog_jr wrote:

Not quite, if ANY of the bits of the result of the AND are non-zero, then the result is true. The ONLY value that represents false is 0x00.

Isn't that what I said in my previous post?

Total votes: 0

chipz wrote:
Isn't that what I said in my previous post?

Yes, I think it is.

The point is that the if() looks at the value of the expression within the parentheses as an int (not a byte), where zero means false and any other value means true.

So, as you said, it only takes one bit to be non-zero for the result to be true.

The if() is not bitwise.