newbie seeks insight on bitwise operations..

A

Alan Holloway

Hi all,

I'm currently learning C (cliche' entry?) and I am finding bitwise
operations a tad challenging. I have a sound understanding of how
boolean logic works (i think), but I find it hard to evaluate the
constructs when I see them in code.

For example, in a network program, a port number is subjected to the
following operation:

port = (port & 0xff) << 8 | port >>8;

AFAIK, port is being assigned the outcome of :

1) An AND operation to ensure that the variable 'port' is not greater
than 255.
2) A left shift by 8 bits (not too sure why though)
3) An OR with the outcome of a right shift by 8 bits (again, not too
sure why).

My apologies for my obvious lack of clue, but i'd really appreciate
some help here in understanding,
as this has been a bit of a show stopper for sometime, and i've
finally realised i'm probably not going to crack this on my own :)

Thanks all

Al.
 
P

pete

Alan said:
Hi all,

I'm currently learning C (cliche' entry?) and I am finding bitwise
operations a tad challenging. I have a sound understanding of how
boolean logic works (i think), but I find it hard to evaluate the
constructs when I see them in code.

For example, in a network program, a port number is subjected to the
following operation:

port = (port & 0xff) << 8 | port >>8;

AFAIK, port is being assigned the outcome of :

1) An AND operation to ensure that the variable 'port' is not greater
than 255.
2) A left shift by 8 bits (not too sure why though)
3) An OR with the outcome of a right shift by 8 bits (again, not too
sure why).

My apologies for my obvious lack of clue, but i'd really appreciate
some help here in understanding,
as this has been a bit of a show stopper for sometime, and i've
finally realised i'm probably not going to crack this on my own :)

If CHAR_BIT equals 8 and sizeof port is 2,
then that will swap the bytes in port.
If not, then it will do something else.
 
J

jacob navia

Alan Holloway said:
Hi all,

I'm currently learning C (cliche' entry?) and I am finding bitwise
operations a tad challenging. I have a sound understanding of how
boolean logic works (i think), but I find it hard to evaluate the
constructs when I see them in code.

For example, in a network program, a port number is subjected to the
following operation:

port = (port & 0xff) << 8 | port >>8;

AFAIK, port is being assigned the outcome of :

1) An AND operation to ensure that the variable 'port' is not greater
than 255.
2) A left shift by 8 bits (not too sure why though)
3) An OR with the outcome of a right shift by 8 bits (again, not too
sure why).

My apologies for my obvious lack of clue, but i'd really appreciate
some help here in understanding,
as this has been a bit of a show stopper for sometime, and i've
finally realised i'm probably not going to crack this on my own :)

Thanks all

Al.

Swapping bytes

It is putting the low byte (port&0xff) in the high byte, and
the high byte in the low byte (port >> 8)

For instance if you had
0xDEAD

you will end having
0xADDE
 
T

Tim Hagan

Alan Holloway said:
Hi all,

I'm currently learning C (cliche' entry?) and I am finding bitwise
operations a tad challenging. I have a sound understanding of how
boolean logic works (i think), but I find it hard to evaluate the
constructs when I see them in code.

For example, in a network program, a port number is subjected to the
following operation:

port = (port & 0xff) << 8 | port >>8;

Assuming that port is a 16-bit unsigned integer, containing two 8-bit
bytes,
this code swaps the two bytes. For example, 0xABCD would be converted to
0xCDAB.
AFAIK, port is being assigned the outcome of :

1) An AND operation to ensure that the variable 'port' is not greater
than 255.

0xff is an 8-bit mask. (port & 0xff) is "grabbing" the right-most byte
of
port.
2) A left shift by 8 bits (not too sure why though)

The result is shifted left 8 bits, filling the right-most byte with
zeros.
3) An OR with the outcome of a right shift by 8 bits (again, not too
sure why).

(port >> 8) shifts port right 8 bits, filling the left-most byte with
zeros.
The result is OR'd with the previously left-shifted right-most byte of
port.
In other words, the left byte is swapped with the right byte, probably
to
compensate for endianess.
 
A

Alex Monjushko

Alan Holloway said:
I'm currently learning C (cliche' entry?) and I am finding bitwise
operations a tad challenging. I have a sound understanding of how
boolean logic works (i think), but I find it hard to evaluate the
constructs when I see them in code.
For example, in a network program, a port number is subjected to the
following operation:
port = (port & 0xff) << 8 | port >>8;
AFAIK, port is being assigned the outcome of :
1) An AND operation to ensure that the variable 'port' is not greater
than 255.
2) A left shift by 8 bits (not too sure why though)
3) An OR with the outcome of a right shift by 8 bits (again, not too
sure why).
My apologies for my obvious lack of clue, but i'd really appreciate
some help here in understanding,
as this has been a bit of a show stopper for sometime, and i've
finally realised i'm probably not going to crack this on my own :)

On a system where CHAR_BIT is 8 and port is a 2 byte integer, this
code will swap the bytes, probably as part of some off-topic
network-to-host or host-to-network byte order conversion.

Imagine that 'port' is something like this:

[10101010][11111111]

1. port & 0xff zeroes the most significant byte.

[00000000][11111111]

2. The 8 bit left-shift will put the least significant byte where
the most significant byte used to be. The least significant byte
is now filled with zeroes.

[11111111][00000000]

3. The 8 bit right-shift, puts the original most significant byte
into the least significant byte position. The most significant byte
is filled with zeroes.

[00000000][10101010]

4. The OR operation combines the two bytes.

[11111111][10101010]
 
K

Keith Thompson

pete said:
If CHAR_BIT equals 8 and sizeof port is 2,
then that will swap the bytes in port.
If not, then it will do something else.

Even if sizeof port > 2 (still assuming CHAR_BIT==8), this will swap
the two low-order bytes of the value of port as long as the initial
value is no greater than 65535. Without assuming CHAR_BIT==8, you can
still say that it swaps the two low-order octets, which may or may not
be "bytes" in the C sense of the word.

If port >= 65536 (i.e., if there are non-zero bits beyond the
low-order 16 bits), other things will happen. If that's going to be
an issue, you might consider preceding the above with
port &= 0xffff;

This all assumes that port is of an unsigned type. If it's signed,
there are rules for the behavior of bitwise operations, but I'm too
lazy to look them up.

BTW, I probably would have written this as

port = ((port & 0xff) << 8) | (port >> 8);

It's equivalent, but I had to check the standard to make sure that
"<<" and ">>" bind more tightly than "|".
 
R

Ravi Uday

> For example, in a network program, a port number is subjected to the

Assuming that port is a 16-bit unsigned integer, containing two 8-bit
bytes,
this code swaps the two bytes. For example, 0xABCD would be converted to
0xCDAB.


0xff is an 8-bit mask. (port & 0xff) is "grabbing" the right-most byte
of
port.


The result is shifted left 8 bits, filling the right-most byte with
zeros.


(port >> 8) shifts port right 8 bits, filling the left-most byte with
zeros.
The result is OR'd with the previously left-shifted right-most byte of
port.
In other words, the left byte is swapped with the right byte, probably
to
compensate for endianess.
We can do this way also:

Ex: Assuming port is 2 byte and CHAR_BIT = 8

unsigned short x = (port << 8);
port = x | (port >> 8);

- Ravi
 
K

kal

port = (port & 0xff) << 8 | port >>8;

This probably has the same effect as the following if
"port" is a 16-bit unsigned short integer.

port = ((port & 0xff) << 8) | ((port >> 8) & 0xff);

<OT>
If this has anything to do with network programming and
the "port" here refers to IP port and it is a 16-bit
unsigned short then it would be better to use one of the
following network library functions that applies to the
situation on hand.

u_short htons(u_short hostshort);
u_short ntohs(u_short netshort);
</OT>
 
A

Alan Holloway

Alex Monjushko said:
Alan Holloway said:
I'm currently learning C (cliche' entry?) and I am finding bitwise
operations a tad challenging. I have a sound understanding of how
boolean logic works (i think), but I find it hard to evaluate the
constructs when I see them in code.
For example, in a network program, a port number is subjected to the
following operation:
port = (port & 0xff) << 8 | port >>8;
AFAIK, port is being assigned the outcome of :
1) An AND operation to ensure that the variable 'port' is not greater
than 255.
2) A left shift by 8 bits (not too sure why though)
3) An OR with the outcome of a right shift by 8 bits (again, not too
sure why).
My apologies for my obvious lack of clue, but i'd really appreciate
some help here in understanding,
as this has been a bit of a show stopper for sometime, and i've
finally realised i'm probably not going to crack this on my own :)

On a system where CHAR_BIT is 8 and port is a 2 byte integer, this
code will swap the bytes, probably as part of some off-topic
network-to-host or host-to-network byte order conversion.

Imagine that 'port' is something like this:

[10101010][11111111]

1. port & 0xff zeroes the most significant byte.

[00000000][11111111]

2. The 8 bit left-shift will put the least significant byte where
the most significant byte used to be. The least significant byte
is now filled with zeroes.

[11111111][00000000]

3. The 8 bit right-shift, puts the original most significant byte
into the least significant byte position. The most significant byte
is filled with zeroes.

[00000000][10101010]

4. The OR operation combines the two bytes.

[11111111][10101010]


All,

Thanks for your help - much clearer now! I think I can use your
replies as a basis for further understanding bitwise operations.

Can you recommend any good links for learning more about bitwise
stuff?

Many thanks for your replies!

Al.
 
E

Eric Sosman

Alan said:
[...]
Can you recommend any good links for learning more about bitwise
stuff?

<http://graphics.stanford.edu/~seander/bithacks.html>

.... but I would *not* recommend indiscriminate use of all
the techniques shown there. Many of them involve non-
portable assumptions about the way the underlying machine
performs arithmetic (for example, about what happens to
the sign bit when a negative integer is right-shifted),
and will fail on machines where the assumptions don't
hold. And, of course, the operation counts that are the
paper's main focus are completely non-portable.

Nonetheless, the snippets make good study subjects
for someone new to bit twiddling.
 
P

pete

Keith said:
I had to check the standard to make sure that
"<<" and ">>" bind more tightly than "|".

Do you really look up precedence and associativity of operators
in the standard ?
I use page 53 of K&R2, instead.
 
K

Keith Thompson

pete said:
Do you really look up precedence and associativity of operators
in the standard ?
I use page 53 of K&R2, instead.

At the moment, the standard is on my laptop, just a few keystrokes
away; my copy of K&R2 is several miles from here.

K&R2 is, of course, a perfectly good resource for this kind of thing.
(So is K&R1; the operator precedence rules haven't changed.) I
presume H&S is as well, but my copy of H&S is busy keeping my K&R2
company.
 

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

No members online now.

Forum statistics

Threads
473,744
Messages
2,569,483
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top