0

I'm attempting to write a (very) short code in C as revision.

According to both my education and other posts such as;

How do you set, clear, and toggle a single bit?

the following code should place the value "1" into the variable ready, and yet, it places the value 64. All the other articles indicate that just the value of the tested bit is placed, not simply the result of the two numbers (number and (1 << x) ) and'ed together - which would indeed be 64! Is this the case or am I simply making an erroneous step?

uart->status |= (1<<6); //Set bit 6 to 1 

char input = 0;

int ready = (uart->status) & (1<<6); //Should mean ready = 1?, a

    if(uart->status & (1<<6) == 1) { //ready actually = 64
        input = uart->rx;
    } else {
        input = 0;
    }

Thanks very much!

David

Community
  • 1
  • 1
davidhood2
  • 1,367
  • 17
  • 47
  • 1
    you're using `&` (bitwise AND(), which will CLEAR bits. to set a bit, you want `|` (bitwise OR) – Marc B Jan 15 '15 at 21:07
  • I want to check the 6th bit of the variable uart->status. If its a 1, then 1&1 will give 1, and if its 0, then the 1&0 will give 0 as the result – davidhood2 Jan 15 '15 at 21:09
  • 1
    The result of `64 & 64` is `64`. I'm not sure why you expect it to be `1`(?). – Michael Jan 15 '15 at 21:11
  • 1
    You had it right here: `ready = (uart->status) & (1<<6); if (ready)...`. You could have tested it specifically with `0x64` but any non-0 value is `true`. – Weather Vane Jan 15 '15 at 21:11

4 Answers4

4

The & operator performs a bitwise AND operation—i.e. it operates independently on each bit, and returns the resulting bits in corresponding locations. So it would, naturally, return 64 if bit 6 was the only location in which both its arguments had a 1.

You may be confusing its behaviour with that of && (which effectively coerces its inputs and output to boolean, and hence will return 1 or 0).

So the problem in your code is purely that you're comparing against the value 1. You could instead say

if(uart->status & (1<<6) != 0)

as user3159253 has pointed out. Or even, of course, just

if( uart->status & (1<<6) )
jez
  • 14,867
  • 5
  • 37
  • 64
2

You're applying a bitwise-AND operation there, so you get the AND'ed value:

int ready = (uart->status) & (1<<6); // 0x00000040 & 0x00000040 = 0x00000040

What do you want? Do you want a flag that you can check whether that bit is set? If so, you're ok, you can do:

if (ready)
{
  // code here
}

And it'll work, since ready is non-zero.

Nick Veys
  • 23,458
  • 4
  • 47
  • 64
  • Thanks - the reason I ask is that previous posts (and in fact what I have been taught!!!) states that the command `test = number & (1 << x);` would do a 1 bit length bitwise AND operation and just "place the value of bit x into the variable test". – davidhood2 Jan 15 '15 at 21:20
  • 1
    Kind of, that's maybe a strange description of it. The `(1 << x)` is just a way of saying "make a value with bit 'x' set to 1". So for `(1 << 4)` it compiles to `0x00000010`. So you've literally written `test = number & 0x00000010`, and you get the bitwise-AND value that results from that operation. – Nick Veys Jan 15 '15 at 21:22
1

The line

if(uart->status & (1<<6) == 1)

should be

if(uart->status & (1<<6) > 0)

when you want to test if bit 6 is set.

** EDIT **

Since you already have the 'ready' variable, it would be better to do

if(ready)
R. Beiboer
  • 712
  • 9
  • 21
  • 2
    That might not work if it was bit 7, depending on how `uart->status` was declared. – Weather Vane Jan 15 '15 at 21:14
  • That's why I said 'when you want to test if bit 6 is set'. But perhaps I don't understand what you mean @Weather Vane. – R. Beiboer Jan 15 '15 at 21:17
  • 1
    Because if the port was declared as `char`, and bit 7 was of interest, testing for positive won't work. It's a matter of good practice - test for non-0. In fact, all you need is `if(uart->status & (1<<6)) {}`. – Weather Vane Jan 15 '15 at 21:18
  • Okay,I see what you mean now, and I agree. And actually, it would be better just to do 'if (ready)' in this case. – R. Beiboer Jan 15 '15 at 21:21
0

This is working as it should. If the bit is set, the value will be greater than 0. If the bit is cleared, the value will be 0. Don't test if it is exactly 1.

Rubix Rechvin
  • 571
  • 3
  • 16