Bit Shifting problem with endieness

M

Madhur

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

Joachim Schmitz

Madhur said:
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
 
R

Richard Bos

Madhur said:
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
 
M

Madhur

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.
 
T

Thad Smith

Madhur said:
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.
 
P

Philip Potter

Madhur said:
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
 
K

Kenneth Brody

[... 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: <mailto:[email protected]>
 
B

Bartc

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.
 

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,744
Messages
2,569,483
Members
44,901
Latest member
Noble71S45

Latest Threads

Top