Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Bit Shifting problem with endieness

Reply
Thread Tools

Bit Shifting problem with endieness

 
 
Madhur
Guest
Posts: n/a
 
      03-10-2008
I am having the following problem of bit shifting.

My program runs on a little endian machine. Consider that if I have
the following data represented in big endian...

0x12345678

the little endian representation would be

0x78563412.

Now if I wan to shift my original data by 4 bits to 0x01234567, then
my approach would be

val = 0x12345678
htonl(htonl(val)>>4)

and result represented in my machine is

0x67452301.

This looks quite redundant to convert little endian to Bid Endian
shift it and then convert back. Basically I thinking of how to get rid
of those two htonl system calls.

I would like to know is there any better way to do this. A best
possibility to shift in little endian mode??
 
Reply With Quote
 
 
 
 
Joachim Schmitz
Guest
Posts: n/a
 
      03-10-2008
Madhur wrote:
> I am having the following problem of bit shifting.
>
> My program runs on a little endian machine. Consider that if I have
> the following data represented in big endian...
>
> 0x12345678
>
> the little endian representation would be
>
> 0x78563412.
>
> Now if I wan to shift my original data by 4 bits to 0x01234567, then
> my approach would be
>
> val = 0x12345678
> htonl(htonl(val)>>4)
>
> and result represented in my machine is
>
> 0x67452301.
>
> This looks quite redundant to convert little endian to Bid Endian
> shift it and then convert back. Basically I thinking of how to get rid
> of those two htonl system calls.
>
> I would like to know is there any better way to do this. A best
> possibility to shift in little endian mode??

I don't think you have an endianess problem:
$ cat a.c
#include <stdio.h>
int main(void) {
int a=0x12345678;
printf("0x%x >> 4 = 0x%x\n", a, a >> 4);
return 0
}
$ cc a.c
$ ./a.out
0x122345678 >> 4 = 0x1234567

Same output on big and little endian machine...

Bye, Jojo


 
Reply With Quote
 
 
 
 
Richard Bos
Guest
Posts: n/a
 
      03-10-2008
Madhur <(E-Mail Removed)> wrote:

> I am having the following problem of bit shifting.
>
> My program runs on a little endian machine.


Bit shifting is defined to work on values, not on their memory
representations, so the endianness of your machine does not matter.

Richard
 
Reply With Quote
 
Madhur
Guest
Posts: n/a
 
      03-10-2008
On Mar 10, 5:35 pm, "Joachim Schmitz" <(E-Mail Removed)>
wrote:
> Madhur wrote:
> > I am having the following problem of bit shifting.

>
> > My program runs on a little endian machine. Consider that if I have
> > the following data represented in big endian...

>
> > 0x12345678

>
> > the little endian representation would be

>
> > 0x78563412.

>
> > Now if I wan to shift my original data by 4 bits to 0x01234567, then
> > my approach would be

>
> > val = 0x12345678
> > htonl(htonl(val)>>4)

>
> > and result represented in my machine is

>
> > 0x67452301.

>
> > This looks quite redundant to convert little endian to Bid Endian
> > shift it and then convert back. Basically I thinking of how to get rid
> > of those two htonl system calls.

>
> > I would like to know is there any better way to do this. A best
> > possibility to shift in little endian mode??

>
> I don't think you have an endianess problem:
> $ cat a.c
> #include <stdio.h>
> int main(void) {
> int a=0x12345678;
> printf("0x%x >> 4 = 0x%x\n", a, a >> 4);
> return 0}
>
> $ cc a.c
> $ ./a.out
> 0x122345678 >> 4 = 0x1234567
>
> Same output on big and little endian machine...
>
> Bye, Jojo


On a big-endian processor, 0x12345678 is stored in consecutive bytes
as 0x12 0x34 0x56 0x78,
while on a little-endian processor it is stored as 0x78 0x56 0x34
0x12.
I am trying to manupulate a buffer neither of ints and longs. As
mentioned if I have a large buffer say 1K bytes to shift by 4 bits,
the problem definitely persists.
 
Reply With Quote
 
Thad Smith
Guest
Posts: n/a
 
      03-10-2008
Madhur wrote:

> On a big-endian processor, 0x12345678 is stored in consecutive bytes
> as 0x12 0x34 0x56 0x78,
> while on a little-endian processor it is stored as 0x78 0x56 0x34
> 0x12.
> I am trying to manupulate a buffer neither of ints and longs. As
> mentioned if I have a large buffer say 1K bytes to shift by 4 bits,
> the problem definitely persists.


Apparently, then, you are treating groups of bytes, or maybe the entire
buffer, as multibyte values. In that case, you decide whether you want to
represent those values in little endian or big endian in your program,
regardless of the natural order used by the processor.

Once decided, write the code. It should work on either type processor.

--
Thad
 
Reply With Quote
 
Philip Potter
Guest
Posts: n/a
 
      03-10-2008
Madhur wrote:
> On a big-endian processor, 0x12345678 is stored in consecutive bytes
> as 0x12 0x34 0x56 0x78,
> while on a little-endian processor it is stored as 0x78 0x56 0x34
> 0x12.
> I am trying to manupulate a buffer neither of ints and longs. As
> mentioned if I have a large buffer say 1K bytes to shift by 4 bits,
> the problem definitely persists.


You say "As mentioned" but I don't see any reference to this previously.

Why do you want to shift 1K bytes by 4 bits? Would it be easier and/or
faster to use a circular buffer with mutable start/end indices instead?

Phil
 
Reply With Quote
 
Kenneth Brody
Guest
Posts: n/a
 
      03-10-2008
Madhur wrote:
>
> On Mar 10, 5:35 pm, "Joachim Schmitz" <(E-Mail Removed)>
> wrote:
> > Madhur wrote:

[... bit-shifting using htonl/shift/ntohl to "solve" the little-endian ...]
[... "problem". ...]
> > > I am having the following problem of bit shifting.

[...]
> > I don't think you have an endianess problem:
> > $ cat a.c
> > #include <stdio.h>
> > int main(void) {
> > int a=0x12345678;
> > printf("0x%x >> 4 = 0x%x\n", a, a >> 4);
> > return 0}
> >
> > $ cc a.c
> > $ ./a.out
> > 0x122345678 >> 4 = 0x1234567
> >
> > Same output on big and little endian machine...
> >
> > Bye, Jojo

>
> On a big-endian processor, 0x12345678 is stored in consecutive bytes
> as 0x12 0x34 0x56 0x78,
> while on a little-endian processor it is stored as 0x78 0x56 0x34
> 0x12.


True, but irrelevent.

> I am trying to manupulate a buffer neither of ints and longs. As
> mentioned if I have a large buffer say 1K bytes to shift by 4 bits,
> the problem definitely persists.


You're overcomplicating things.

You aren't "manipulating a buffer", you're "manipulating a _value_".
when you have:

int a = 0x12345678;

it doesn't matter whether you are on a big- or little-endian system.
When you execute:

int b = a >> 4;

you are not treating a as a buffer of (4, in this case) unrelated
bytes. Rather, you are treating it as a single (32-bit, in this
case) value.

At the machine code, you may end up with something like this:

move eax,_a ; This stores 0x12345678 into the eax register
sar eax,4 ; ">> 4"
move _b,eax ; This stores 0x01234567 into b

--
+-------------------------+--------------------+-----------------------+
| Kenneth J. Brody | www.hvcomputer.com | #include |
| kenbrody/at\spamcop.net | www.fptech.com | <std_disclaimer.h> |
+-------------------------+--------------------+-----------------------+
Don't e-mail me at: <(E-Mail Removed)>


 
Reply With Quote
 
Bartc
Guest
Posts: n/a
 
      03-10-2008

"Madhur" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> On Mar 10, 5:35 pm, "Joachim Schmitz" <(E-Mail Removed)>
> wrote:
>> Madhur wrote:
>> > I am having the following problem of bit shifting.


> On a big-endian processor, 0x12345678 is stored in consecutive bytes
> as 0x12 0x34 0x56 0x78,
> while on a little-endian processor it is stored as 0x78 0x56 0x34
> 0x12.
> I am trying to manupulate a buffer neither of ints and longs. As
> mentioned if I have a large buffer say 1K bytes to shift by 4 bits,
> the problem definitely persists.


The problem needs to be specified more precisely. If the first few bytes of
your buffer are:

0x12 0x34 0x56 0x78 ...

then each byte is being displayed high-nibble (or nybble) first and a 4-bit
shift of the entire buffer is ambiguous. If you display your data as:

0x1 0x2 0x3 0x4 0x5 0x6 0x7 0x8 ...

Then a left-shift of 4-bits (1 nibble) is unambiguous (you end up with 0x2,
0x3 etc). But you need to define how pairs of nibbles are represented in
each byte (as 12, 34 or 21, 43).

It might well be simpler to just store one nibble in each byte; will waste
memory but shifting is far simpler.

Or, if you want to shift 32 bits at a time, reorganise each group of 8
nibbles according to your memory layout, perhaps as 0x87654321 (a left shift
becomes a 32-bit right shift) or as 0x12345678 (left shift is still right
shift). But the memory layout in the latter case might be 0x78 0x56 0x34
0x12.

--
Bart


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
What is the point of having 16 bit colour if a computer monitor can only display 8 bit colour? How do you edit 16 bit colour when you can only see 8 bit? Scotius Digital Photography 6 07-13-2010 03:33 AM
shifting bits, shift 32 bits on 32 bit int GGG C++ 10 07-06-2006 06:09 AM
Bit-shifting to multiply and divide? Nobody C++ 6 11-15-2004 08:55 AM
64 bit - Windows Liberty 64bit, Windows Limited Edition 64 Bit, Microsoft SQL Server 2000 Developer Edition 64 Bit, IBM DB2 64 bit - new ! vvcd Computer Support 0 09-17-2004 08:15 PM
64 bit - Windows Liberty 64bit, Windows Limited Edition 64 Bit,Microsoft SQL Server 2000 Developer Edition 64 Bit, IBM DB2 64 bit - new! Ionizer Computer Support 1 01-01-2004 07:27 PM



Advertisments