Bitwise operation doesn't work

A

Andrew Usher

This line should set to 0 one bit of an array (of 32-bit values):

P[[(c>>5)]]&=(!((0x00000001)<<(c2&0x0000001f)));

but it actually sets the whole word to zero. Since this is obviously
logically correct, can C not handle these things? I'm sure I have to
rewrite the whole god-damned thing in assembler.

Andrew Usher
 
K

Keith Thompson

Andrew Usher said:
This line should set to 0 one bit of an array (of 32-bit values):

P[[(c>>5)]]&=(!((0x00000001)<<(c2&0x0000001f)));

but it actually sets the whole word to zero. Since this is obviously
logically correct, can C not handle these things?
[...]

It's not "obviously" logically correct without seeing the context.

Post a small complete program that exhibits the problem; tell us what
output you expected and what output you actually get.
 
E

Eric Sosman

This line should set to 0 one bit of an array (of 32-bit values):

P[[(c>>5)]]&=(!((0x00000001)<<(c2&0x0000001f)));

but it actually sets the whole word to zero. Since this is obviously
logically correct, can C not handle these things? I'm sure I have to
rewrite the whole god-damned thing in assembler.

Perhaps you should review the the ! and the ~ operators,
and ponder why C has both, and speculate on what difference
there could possibly be between them.

Just a thought.
 
B

bartc

Andrew Usher said:
This line should set to 0 one bit of an array (of 32-bit values):

P[[(c>>5)]]&=(!((0x00000001)<<(c2&0x0000001f)));

but it actually sets the whole word to zero. Since this is obviously
logically correct, can C not handle these things? I'm sure I have to
rewrite the whole god-damned thing in assembler.

Those double square brackets don't look right; perhaps there's a name
missing between those first two [[.

What's the value of the right-hand-side of the assignment at the point where
it doesn't work?

What's the value of the index to P?

If these values are A and B, then would you expect P &= A to do what you
want? If not then you might need to change the code.
 
B

Ben Bacarisse

Andrew Usher said:
This line should set to 0 one bit of an array (of 32-bit values):

P[[(c>>5)]]&=(!((0x00000001)<<(c2&0x0000001f)));

but it actually sets the whole word to zero. Since this is obviously
logically correct, can C not handle these things?

There is a syntax error and lots of noise in that expression. If we
make the obvious correction to the synatx (P[[E]] should be P[E]) and
remove the noise, we get:

P[c>>5] &= !(1u << (c2 & 0x1f));

1u << by any number from 0 to 31 will be non-zero so ! of it will be
zero. ANDing with zero gives zero. You probably want ~ rather than !.

You really want 1u rather the 1 or 0x00000001 as the number to shift.
Also, you may want c in both places rather than c and c2.

<snip>
 
L

Lew Pitcher

This line should set to 0 one bit of an array (of 32-bit values):

P[[(c>>5)]]&=(!((0x00000001)<<(c2&0x0000001f)));

but it actually sets the whole word to zero.

That's a complex statement you got there. Let's break it down into it's
parts

The RHS breaks down as

(c2 & 0x1f) results in an int between 0 and 31 (assuming c2 is an int)

0x01 << (c2 & 0x1f) results in one of 32 bits being set (assuming that
0x01 is a 32bit integer), making the result non-zero

!(0x01 << (c2 & 0x1f)) results in zero. ! changes zero values to 1 and
non-zero values to 0

So, on the RHS, we have 0 (or some sort of violation, for a non-int c2 or
ints that are smaller than 32bits wide)

The assignment operator is &=, which LOGICAL-ANDs the LHS with the RHS and
assigns the resulting value to the LHS.

Any integer LOGICAL-ANDed with 0 results in 0, so the LHS gets assigned 0


Let's look at that LHS:
P[[(c>>5)]]

Hmmmmm..... that's a notation that I'm unfamiliar with. Pedants and experts,
is that even a legal C construct?

I'm specifically referring to
P[[...]]
an anonymous subscript *within* a subscript?
Since this is obviously logically correct,

Not so obviously. Certainly, it depends on some context, both with other
code (what sort of data items are <<c>> and <<c2>>?) and on the
capabilities of the compiler and environment you are working with (how big
is an int? what does the C compiler think of said:
can C not handle these things? I'm sure I have to
rewrite the whole god-damned thing in assembler.

If you can, and you think that C won't handle the expression you are trying
to build, why don't you rewrite it in Assembler. Certainly, we have no
emotional investment in the languages you choose to write your code in.
 
D

Doug Miller

This line should set to 0 one bit of an array (of 32-bit values):

P[[(c>>5)]]&=(!((0x00000001)<<(c2&0x0000001f)));

but it actually sets the whole word to zero. Since this is obviously
logically correct, can C not handle these things?

In fact, it is obviously logically INcorrect. C handles "these things" just
fine. It's doing exactly what you told it to.

Hint: ! doesn't do what you think it does.
 
K

Keith Thompson

This line should set to 0 one bit of an array (of 32-bit values):

P[[(c>>5)]]&=(!((0x00000001)<<(c2&0x0000001f)));

but it actually sets the whole word to zero. Since this is obviously
logically correct, can C not handle these things?

In fact, it is obviously logically INcorrect. C handles "these things" just
fine. It's doing exactly what you told it to.

Hint: ! doesn't do what you think it does.

It doesn't do anything; it's a syntax error.

I don't believe it's possible to have two consecutive "[" tokens in a
valid C program.
 
P

Peter Nilsson

Keith Thompson said:
...I don't believe it's possible to have two consecutive
"[" tokens in a valid C program.

#include <stdio.h>

#define STR(x) #x

int main(void)
{
puts(STR([[));
return 0;
}
 
A

Andrew Usher

Doug said:
This line should set to 0 one bit of an array (of 32-bit values):

P[[(c>>5)]]&=(!((0x00000001)<<(c2&0x0000001f)));

but it actually sets the whole word to zero. Since this is obviously
logically correct, can C not handle these things?

In fact, it is obviously logically INcorrect. C handles "these things" just
fine. It's doing exactly what you told it to.

Hint: ! doesn't do what you think it does.

OK, I'll reply to all of you.

First, I typed in this line by hand which accounts for the syntax
error and the c/c2 difference - I name all my random integer variables
c, c2, etc. and sometimes get them mixed up.

It was indeed the ! operator that was wrong. I'd never heard of the ~
operator before, but I figured it out from this thread. I never
learned C formally, and have never seen a list of all the features of
C, such as operators.

Andrew Usher
 
K

Keith Thompson

Peter Nilsson said:
Keith Thompson said:
...I don't believe it's possible to have two consecutive
"[" tokens in a valid C program.

#include <stdio.h>

#define STR(x) #x

int main(void)
{
puts(STR([[));
return 0;
}

Where are the "[" tokens? All I see is a pair of "[" preprocessing
tokens.

(Good answer nonetheless.)
 
I

Ian Collins

Andrew said:
Doug said:
This line should set to 0 one bit of an array (of 32-bit values):

P[[(c>>5)]]&=(!((0x00000001)<<(c2&0x0000001f)));

but it actually sets the whole word to zero. Since this is obviously
logically correct, can C not handle these things?
In fact, it is obviously logically INcorrect. C handles "these things" just
fine. It's doing exactly what you told it to.

Hint: ! doesn't do what you think it does.

OK, I'll reply to all of you.

First, I typed in this line by hand which accounts for the syntax
error and the c/c2 difference - I name all my random integer variables
c, c2, etc. and sometimes get them mixed up.

It was indeed the ! operator that was wrong. I'd never heard of the ~
operator before, but I figured it out from this thread. I never
learned C formally, and have never seen a list of all the features of
C, such as operators.

Then you should buy a copy of K&R2 without delay!
 
M

Mark Bluemel

It was indeed the ! operator that was wrong. I'd never heard of the ~
operator before, but I figured it out from this thread. I never
learned C formally, and have never seen a list of all the features of
C, such as operators.

Should we introduce this guy to Bill?
 
E

Eric Sosman

[...]
It was indeed the ! operator that was wrong. I'd never heard of the ~
operator before, but I figured it out from this thread. I never
learned C formally, and have never seen a list of all the features of
C, such as operators.

Ah, so your antagonistic tone in "Since this is obviously
logically correct, can C not handle these things?" was utterly
unwarranted?

Seriously: If you expect to get any value out of using a
tool, particularly an intricate tool like a programming language,
you had better plan on spending some time learning what the tool
does. If your hammer applies paint unevenly, don't blame the
hammer!
 
E

Edward A. Falk

This line should set to 0 one bit of an array (of 32-bit values):

P[[(c>>5)]]&=(!((0x00000001)<<(c2&0x0000001f)));

OK, first, why did you make it so unreadable? Is this part of some
obfuscated programming contest?

P[[c>>5]] &= !(1 << (c2 & 0x1f));

That's a little better.

OK, now I see your problem. Learn the differences between ! and ~
 
A

Andrew Usher

Eric said:
[...]
It was indeed the ! operator that was wrong. I'd never heard of the ~
operator before, but I figured it out from this thread. I never
learned C formally, and have never seen a list of all the features of
C, such as operators.

Ah, so your antagonistic tone in "Since this is obviously
logically correct, can C not handle these things?" was utterly
unwarranted?

Strictly, I wasn't wrong: it is _logically_ correct, in that it
expresses what I meant, it just isn't proper C. But I suppose it was
excessive.

Andrew Usher
 

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,777
Messages
2,569,604
Members
45,217
Latest member
IRMNikole

Latest Threads

Top