Velocity Reviews > Bit Shifting problem with endieness

# 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??

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

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

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.

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

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

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)>

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

 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 OffTrackbacks are On Pingbacks are On Refbacks are Off Forum Rules

 Similar Threads Thread Thread Starter Forum Replies Last Post Scotius Digital Photography 6 07-13-2010 03:33 AM GGG C++ 10 07-06-2006 06:09 AM Nobody C++ 6 11-15-2004 08:55 AM vvcd Computer Support 0 09-17-2004 08:15 PM Ionizer Computer Support 1 01-01-2004 07:27 PM

Advertisments