473,395 Members | 1,437 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

More bitwise woes

I am trying to do some bit fiddling with unsigned chars. Don't ask me
why I am doing this, I don't know. It's just an exercise. :)

Here's what I am trying to do: I have one unsigned char of a certain
pattern, and four unsigned chars all with the bit pattern 010 00 010.
The first two binary bits leftmost of the first will go in the middle of
the first char with the bit pattern 010 00 010. The second lot of bits
from the first char will go in the middle of the second char with the
bit pattern 010 00 010. And so on for bits 2, 3 and bits 0, 1 of the
first char.

So, here are the chars with the 010 00 010 patterns.

unsigned char finished[4];
finished[0] |= (0x02 << 5);
finished[0] |= 0x02;

.... and so on for finished[1-3].

And now I have a char with whatever in it, say 'H'.

unsigned char ch = 'H';

Now, I want the leftmost two bits in the middle of finished[0]. What I
attempt to do is OR ch with 0xC0, which gets me just the two leftmost
bits. Then shift them 3 places to the right, to get them in the middle
of the 8-bit char. Then OR with 0x18, which gets me just the two middle
bits, which were previously the leftmost two bits before they were
shifted down into the middle:

finished[0] |= (3 >> (0xC0 & ch)) & 0x18;

Now for finished[1], which has the same 010 00 010 bit pattern, and the
next two leftmost bits of ch, which are bits 4 and 5 (counting from 0
from the left).

This attempts to get a mask for just bits 4 and 5 in ch, shifts them one
place down to the right to get them in the middle, then gets those two
middle bits:

finished[1] |= (1 >> (0x30 & ch)) & 0x18;

Now for finished[2]:

finished[2] |= ((0x0C & ch) << 1) & 0x18;

And for finished[3]:

finished[3] |= ((0x03 & ch) << 3) & 0x18;

Problem is I can't make it work. Am I doing something wrong?

Thanks for your help.

Johnathan
Nov 14 '05 #1
7 1586
finished[0] |= (0xC0 & ch) >> 3;
finished[1] |= (0x30 & ch) >> 1;
finished[2] |= (0x0C & ch) << 1;
finished[3] |= (0x03 & ch) << 3;

alternatively:

finished[0] |= (ch >> 3) & 0x18;
finished[1] |= (ch >> 1) & 0x18;
finished[2] |= (ch << 1) & 0x18;
finished[3] |= (ch << 3) & 0x18;

Regards
Sasca
Nov 14 '05 #2
Johnathan Doe <No-spam-here-johnathan_doe@!!!nospamthanks!!!fastmail.com.au> wrote:
I am trying to do some bit fiddling with unsigned chars. Don't ask me
why I am doing this, I don't know. It's just an exercise. :) Here's what I am trying to do: I have one unsigned char of a certain
pattern, and four unsigned chars all with the bit pattern 010 00 010.
The first two binary bits leftmost of the first will go in the middle of
the first char with the bit pattern 010 00 010. The second lot of bits
from the first char will go in the middle of the second char with the
bit pattern 010 00 010. And so on for bits 2, 3 and bits 0, 1 of the
first char. So, here are the chars with the 010 00 010 patterns. unsigned char finished[4];
finished[0] |= (0x02 << 5);
The '|=' here is dangerous since - at least the way you show it here -
the elements of 'finished' probably aren't initialized, so finished[0]
could be some random value to which you 'or' 0x40.
finished[0] |= 0x02;
Why not make that

finished[0] = 0x02 << 5 | 0x02;

or just

finished[0] = 0x42;
... and so on for finished[1-3].
I don't understand why you do all that, to me it looks like an overly
complicated way of just having

unsigned char finished[4] = { 0x42, 0x42, 0x42, 0x42 };
And now I have a char with whatever in it, say 'H'. unsigned char ch = 'H'; Now, I want the leftmost two bits in the middle of finished[0]. What I
attempt to do is OR ch with 0xC0, which gets me just the two leftmost
bits. Then shift them 3 places to the right, to get them in the middle
of the 8-bit char. Then OR with 0x18, which gets me just the two middle
bits, which were previously the leftmost two bits before they were
shifted down into the middle: finished[0] |= (3 >> (0xC0 & ch)) & 0x18;
Here you are shifting the bits of the value 3 to the right - with both
'<<' and '>>' the value to be shifted is on the left of the operator,
the number of bits to shift on the right. But in the text you write you
want to shift the upper two bits to the right by 3 positions. So

finished[0] |= ( ch & 0xC0 ) >> 3;

is what you need - you can drop the "& 0x18" part since the "& 0xC0"
made already sure only the two bits can be set.
Now for finished[1], which has the same 010 00 010 bit pattern, and the
next two leftmost bits of ch, which are bits 4 and 5 (counting from 0
from the left). This attempts to get a mask for just bits 4 and 5 in ch, shifts them one
place down to the right to get them in the middle, then gets those two
middle bits: finished[1] |= (1 >> (0x30 & ch)) & 0x18;
Same problem here

finished[1] |= ( ch & 0x30 ) >> 1;
Now for finished[2]: finished[2] |= ((0x0C & ch) << 1) & 0x18;
This looks ok (but you can also drop the "& 0x18" part here).
And for finished[3]: finished[3] |= ((0x03 & ch) << 3) & 0x18;


Ditto.
Regards, Jens
--
\ Jens Thoms Toerring ___ Je***********@physik.fu-berlin.de
\__________________________ http://www.toerring.de
Nov 14 '05 #3
In article <41***********************@per-qv1-newsreader-01.iinet.net.au>,
Johnathan Doe
<No-spam-here-johnathan_doe@!!!NOSPAMTHANKS!!!fastmail.com.au> wrote:
I am trying to do some bit fiddling with unsigned chars. Don't ask me
why I am doing this, I don't know. It's just an exercise. :) Here's what I am trying to do: I have one unsigned char of a certain
pattern, and four unsigned chars all with the bit pattern 010 00 010.
The first two binary bits leftmost of the first will go in the middle of
the first char with the bit pattern 010 00 010. The second lot of bits
from the first char will go in the middle of the second char with the
bit pattern 010 00 010. And so on for bits 2, 3 and bits 0, 1 of the
first char.
If I read this correctly, given a byte with the form:
b0 b1 b2 b3 b4 b5 b6 b7

you want to end up with the series of bytes:

0: 010 b0 b1 010
1: 010 b2 b3 010
2: 010 b4 b5 010
3: 010 b6 b7 010
So, here are the chars with the 010 00 010 patterns. unsigned char finished[4];
finished[0] |= (0x02 << 5);
finished[0] |= 0x02; ... and so on for finished[1-3]. And now I have a char with whatever in it, say 'H'. unsigned char ch = 'H'; Now, I want the leftmost two bits in the middle of finished[0]. What I
attempt to do is OR ch with 0xC0, which gets me just the two leftmost
bits. Then shift them 3 places to the right, to get them in the middle
of the 8-bit char. Then OR with 0x18, which gets me just the two middle
bits, which were previously the leftmost two bits before they were
shifted down into the middle: finished[0] |= (3 >> (0xC0 & ch)) & 0x18;


You are saying OR in the text but then anding in the code. Also you have
the values the wrong way round for the shift, the value to shift is first
then the shift sign then the amount to shift by.

What you need to do (I think) is to shift the value of ch right by 3 bits,
then AND the value with 0x18. Which gives you the code:

finished[ 0 ] |= ( ch >> 3 ) & 0x18;

then for the other three bytes you just need to alter the direction and
sive of the shift.

Hope this helps.

Kevin.

Nov 14 '05 #4
Thankyou thankyou thankyou, Sasca and Jens!!

This has stumped me for days! In my 5 years of C programming the only
thing I never "got" was bitwise stuff. Now I am finally starting to
understand it.

Thanks for your help. :)
Nov 14 '05 #5
kevin.bagust wrote:
If I read this correctly, given a byte with the form:
b0 b1 b2 b3 b4 b5 b6 b7

you want to end up with the series of bytes:

0: 010 b0 b1 010
1: 010 b2 b3 010
2: 010 b4 b5 010
3: 010 b6 b7 010
That's correct, yes.
You are saying OR in the text but then anding in the code. Also you have
the values the wrong way round for the shift, the value to shift is first
then the shift sign then the amount to shift by.

What you need to do (I think) is to shift the value of ch right by 3 bits,
then AND the value with 0x18. Which gives you the code:

finished[ 0 ] |= ( ch >> 3 ) & 0x18;

then for the other three bytes you just need to alter the direction and
sive of the shift.

Hope this helps.


It does, thanks heaps. :)

I was confused on the issue of what gets shifted and what is how much to
shift by. I had them round the wrong way and all sorts! And didn't
need the final mask since I had already gotten the bits I was interested
in, etc.

Cheers
Johnathan
Nov 14 '05 #6
"kevin.bagust" <ke**********@ntlworld.com> wrote in message
news:4d13d52859ke**********@ntlworld.com...
If I read this correctly, given a byte with the form:
b0 b1 b2 b3 b4 b5 b6 b7

you want to end up with the series of bytes:

0: 010 b0 b1 010
1: 010 b2 b3 010
2: 010 b4 b5 010
3: 010 b6 b7 010


It is a bit misleading to number bits this way.

Even though it is merely a matter of conventions, I find much more consistent to
number bits from the least significant to the most significant starting at 0.
It is more consistent because it makes the value of bx be 1<<x or 2 to the x.
Most hardware vendors use this convention. IBM is among the few that use the
opposite convention, starting at 1, creating much confusion among hardware
specification readers.

The character in the OP's question would then be :
b7 b6 b5 b4 b3 b2 b1 b0

and the intended result:

0: 0 1 0 b7 b6 0 1 0
1: 0 1 0 b5 b4 0 1 0
2: 0 1 0 b3 b2 0 1 0
3: 0 1 0 b1 b0 0 1 0

--
Chqrlie.
Nov 14 '05 #7
On Wed, 1 Dec 2004 13:40:17 +0100, Charlie Gordon
<ne**@chqrlie.org> wrote:
Even though it is merely a matter of conventions, I find much more consistent to
number bits from the least significant to the most significant starting at 0.
It is more consistent because it makes the value of bx be 1<<x or 2 to the x.
Most hardware vendors use this convention. IBM is among the few that use the
opposite convention, starting at 1, creating much confusion among hardware
specification readers.
Several of the European telcommunications specifications start with bit
0 as the high bit. I believe they were written by the French (this
explains a lot of weird things)...
The character in the OP's question would then be :
b7 b6 b5 b4 b3 b2 b1 b0

and the intended result:

0: 0 1 0 b7 b6 0 1 0
1: 0 1 0 b5 b4 0 1 0
2: 0 1 0 b3 b2 0 1 0
3: 0 1 0 b1 b0 0 1 0


I find that a lot more logical as well...

Chris C
Nov 14 '05 #8

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

9
by: Michael B. Trausch | last post by:
I have a question regarding bitwise operators, I've been trying to figure this out for about two days now, and I just can't seem to get it. What I'm trying to do is use a variable to hold a bitmask...
6
by: jas_lx | last post by:
The basic understanding of what bitwise operators (& ^ | >> << ) comes fairly simple, as long as one has a fundamental understanding of bits, bytes and binary. Having done some Win32...
10
by: Emilio | last post by:
Do I use 'or' for bitwise operations where in c# I use | ?
5
by: noridotjabi | last post by:
I'm learning to program in C and any tutorial or book that I read likes to briefly touch on birdies operators and then move on without giving any sort of example application of them. Call me what...
17
by: zirconx | last post by:
I'm trying to understand how the bitwise AND can be used. I've read about what it does but am having trouble applying it practically. I'm working on a system that somebody else wrote and they...
3
by: Jay Ruyle | last post by:
I'm trying to figure out a way to list several items in a listbox and let the user select any number of items in the listbox. I have tried to code in the items as bitwise items but all it stores...
5
by: Gigs_ | last post by:
Can someone explain me bitwise expression? few examples for every expression will be nice x << y Left shift x >y Right shift x & y Bitwise AND x | y Bitwise OR x ^ y Bitwise XOR (exclusive...
9
by: Mark Rae | last post by:
Hi, This time, I'm looking for a regular expression which says "the string must contain exactly seven or exactly eight digits" e.g. 123456 fails 1234567 passes 12345678 passes 123456789...
3
by: Sakhtkoosh | last post by:
I have written a program in C environment. I need to do operation on codes with more than 64 elements whose values are 0 and 1. At first, I simulated it with an array in 2 dimension(n*m) but after...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.