Bit masks and nature of equality

M

moogyd

Hi,

I have debugged and fixed some code, but don't really understand the
behavior I have seen.

The following code compiles and runs with noo warnings (gcc 4.3.2 with
-Wall and -pendantic)

#include <stdio.h>
int main() {
int mask = 0x01 ;
int x = 0x80 ;
if (!(mask & x) == mask) {
printf("Match\n") ;
}
return 0 ;
}
When I run, it prints "Match" which I don't understand
My logic (note I am not a C programmer)
(mask & x) Evaluates to 0
!(mask & x) Evaluates to not 0. i.e. A positive number (I assumed
0x01)
So, the results of
!(mask & x) == mask *should* be false (but it obviously isn't :-(

My initial assumption was that the compiler was casting everything to
a common type (bool) due to the parenthesis on (mask & x). However, in
this case, I was hoping the gcc would warn me.

So, can anyone provide any clarification, or confirm my assumptions.

Thanks,

Steven
 
E

Eric Sosman

Hi,

I have debugged and fixed some code, but don't really understand the
behavior I have seen.

The following code compiles and runs with noo warnings (gcc 4.3.2 with
-Wall and -pendantic)

#include<stdio.h>
int main() {
int mask = 0x01 ;
int x = 0x80 ;
if (!(mask& x) == mask) {
printf("Match\n") ;
}
return 0 ;
}
When I run, it prints "Match" which I don't understand
My logic (note I am not a C programmer)
(mask& x) Evaluates to 0

Right.
!(mask& x) Evaluates to not 0. i.e. A positive number (I assumed
0x01)

Right.
So, the results of
!(mask& x) == mask *should* be false (but it obviously isn't :-(

Why do you think `0x1 == 0x1' should be false?

Let's step through it again, starting with the expression
as written:

!(mask & x) == mask

Substitute the value of mask:

!(0x1 & x) == 0x1

Substitute the value of x:

!(0x1 & 0x80) == 0x1

Evaluate the and:

!(0) == 0x1

Evaluate the not:

1 == 0x1

Evaluate the comparison:

1

Anything non-zero is "true" in C, so the `if' is satisfied and
the printf() call is executed.
 
C

crisgoogle

Hi,

I have debugged and fixed some code, but don't really understand the
behavior I have seen.

The following code compiles and runs with noo warnings (gcc 4.3.2 with
-Wall and -pendantic)

#include <stdio.h>
int main() {
    int mask = 0x01 ;
    int x = 0x80 ;
    if (!(mask & x) == mask) {
        printf("Match\n") ;
    }
    return 0 ;}

When I run, it prints "Match" which I don't understand
My logic (note I am not a C programmer)
(mask & x)  Evaluates to 0
!(mask & x) Evaluates to not 0. i.e. A positive number (I assumed
0x01)

Never assume! (But you were right this time.)
So, the results of
!(mask & x) == mask *should* be false (but it obviously isn't :-(

You must have some sort of mental block from looking at this bit of
code for too long or something, because your analysis seems fairly
logical except for one glaring error =)

Yes, mask & x evaluates to 0.
Yes, !0 evaluates to 1.

How on earth did you then decide that 1 == 1 should be false??
My initial assumption was that the compiler was casting everything to
a common type (bool) due to the parenthesis on (mask & x). However, in
this case, I was hoping the gcc would warn me.

No, parentheses or not, everything here will remain as ints. And the
compiler never casts anything (unless you tell it to, with a cast),
though of course it may convert, under circumstances other than what
you're doing here.
 
B

Ben Bacarisse

moogyd said:
The following code compiles and runs with noo warnings (gcc 4.3.2 with
-Wall and -pendantic)

You might also want -ansi (or -std=c90 or -std=c99) and maybe -Wextra.
#include <stdio.h>
int main() {
int mask = 0x01 ;
int x = 0x80 ;
if (!(mask & x) == mask) {
printf("Match\n") ;
}
return 0 ;
}
When I run, it prints "Match" which I don't understand
My logic (note I am not a C programmer)
(mask & x) Evaluates to 0
Yup.

!(mask & x) Evaluates to not 0. i.e. A positive number (I assumed
0x01)

That's right. !0 is 1 -- every time on all systems. It is how C is
specified. 0x01 is just another way to write 1 so you are right to have
guessed that the result is 0x01. It is also 0x1 and 0x00001 and 001 and
several others that are ways to write the same thing.
So, the results of
!(mask & x) == mask *should* be false (but it obviously isn't :-(

I can't see why you think this. !(mask & x) is 1. mask is 0x01. 0x01
and 1 are two ways to write the same value so they must compare equal.
My initial assumption was that the compiler was casting everything to
a common type (bool) due to the parenthesis on (mask & x). However, in
this case, I was hoping the gcc would warn me.

So, can anyone provide any clarification, or confirm my assumptions.

I'm not sure where the confusion come from.
 
M

moogyd

Hi,

I have debugged and fixed some code, but don't really understand the
behavior I have seen.

The following code compiles and runs with noo warnings (gcc 4.3.2 with
-Wall and -pendantic)

#include <stdio.h>
int main() {
    int mask = 0x01 ;
    int x = 0x80 ;
    if (!(mask & x) == mask) {
        printf("Match\n") ;
    }
    return 0 ;}

When I run, it prints "Match" which I don't understand
My logic (note I am not a C programmer)
(mask & x)  Evaluates to 0
!(mask & x) Evaluates to not 0. i.e. A positive number (I assumed
0x01)
So, the results of
!(mask & x) == mask *should* be false (but it obviously isn't :-(

My initial assumption was that the compiler was casting everything to
a common type (bool) due to the parenthesis on (mask & x). However, in
this case, I was hoping the gcc would warn me.

So, can anyone provide any clarification, or confirm my assumptions.

Thanks,

Steven

Sorry for the noise. As people have correctly pointed out,
0x01==0x01 !.

In my (very limited defence), this is a simplification of the real
problem I have, which I have been looking it all day.

Therefore, the mental block caused me to produce a very poor example
(and waste everyones time).

Sorry again,

Steven
 
S

Seebs

The following code compiles and runs with noo warnings (gcc 4.3.2 with
-Wall and -pendantic)

#include <stdio.h>
int main() {
int mask = 0x01 ;
int x = 0x80 ;
if (!(mask & x) == mask) {
printf("Match\n") ;
}
return 0 ;
}
When I run, it prints "Match" which I don't understand

Consider:

mask & x # 0
(mask & x) == mask
=> 0 == 0x1 # 0
!((mask & x) == mask) # 1

-s
 
S

Seebs

So, can anyone provide any clarification, or confirm my assumptions.

Several people did, but ignore my attempted answer, I didn't sleep
enough apparently. That was unusually dazed even for me.

Yes, !0 == 1.

-s
 
S

Seebs

Consider:

mask & x # 0
(mask & x) == mask
=> 0 == 0x1 # 0
!((mask & x) == mask) # 1

.... Also consider going back on the caffeine. Yes, that might help.

I think I somehow convinced myself that mask was 80 and x was 1, and then
ignored everything I knew about precedence and expression grouping to come
up with a theory as to how this could have happened, even though it was
obviously wrong.

Remember: A full night of sleep is a GOOD THING.

-s
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,996
Messages
2,570,238
Members
46,826
Latest member
robinsontor

Latest Threads

Top