Bit Shifting problem with endieness

Discussion in 'C Programming' started by Madhur, Mar 10, 2008.

  1. Madhur

    Madhur Guest

    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??
     
    Madhur, Mar 10, 2008
    #1
    1. Advertising

  2. 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
     
    Joachim Schmitz, Mar 10, 2008
    #2
    1. Advertising

  3. Madhur

    Richard Bos Guest

    Madhur <> 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
     
    Richard Bos, Mar 10, 2008
    #3
  4. Madhur

    Madhur Guest

    On Mar 10, 5:35 pm, "Joachim Schmitz" <>
    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.
     
    Madhur, Mar 10, 2008
    #4
  5. Madhur

    Thad Smith Guest

    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
     
    Thad Smith, Mar 10, 2008
    #5
  6. 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
     
    Philip Potter, Mar 10, 2008
    #6
  7. Madhur wrote:
    >
    > On Mar 10, 5:35 pm, "Joachim Schmitz" <>
    > 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: <mailto:>
     
    Kenneth Brody, Mar 10, 2008
    #7
  8. Madhur

    Bartc Guest

    "Madhur" <> wrote in message
    news:...
    > On Mar 10, 5:35 pm, "Joachim Schmitz" <>
    > 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
     
    Bartc, Mar 10, 2008
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. GGG
    Replies:
    10
    Views:
    12,741
    Donar
    Jul 6, 2006
  2. Nobody
    Replies:
    6
    Views:
    11,996
    Niels Dybdahl
    Nov 15, 2004
  3. Rick

    Bit shifting for log of 2

    Rick, Oct 1, 2003, in forum: C Programming
    Replies:
    7
    Views:
    1,077
    Mathew Hendry
    Oct 13, 2003
  4. ben
    Replies:
    8
    Views:
    405
  5. ben

    small bit shifting q

    ben, Mar 4, 2004, in forum: C Programming
    Replies:
    4
    Views:
    385
    xarax
    Mar 5, 2004
Loading...

Share This Page