How to determine the byte order of machine.

Discussion in 'C Programming' started by somenath, Feb 20, 2012.

  1. somenath

    somenath Guest

    Hello All,
    Is the following program can correctly determine the byte order of the
    machine?
    #include<stdio.h>
    int main(void)
    {
    unsigned int x =1;
    if ((x>>1) == 0)
    printf("little-endian\n");
    else
    printf("Big-endian \n");
    return 0;
    }
    In my opinion in case of little endian the 1 will be stored at the
    last byte of the variable x. so if I shift it 1 byte the variable x
    will have 0.But in case of big-endian 1 will be store at the right
    most bye so right shifting by 1 should not be obtain 0. Is my
    understanding correct?
    I did not have access to big-endian machine. So i have not checked the
    program in big-endian machine.

    Thanks.
    Somenath
     
    somenath, Feb 20, 2012
    #1
    1. Advertising

  2. somenath <> writes:

    > Hello All,
    > Is the following program can correctly determine the byte order of the
    > machine?


    No. The output is independent of the way in which values are stored.

    > #include<stdio.h>
    > int main(void)
    > {
    > unsigned int x =1;
    > if ((x>>1) == 0)
    > printf("little-endian\n");
    > else
    > printf("Big-endian \n");
    > return 0;
    > }
    > In my opinion in case of little endian the 1 will be stored at the
    > last byte of the variable x. so if I shift it 1 byte the variable x
    > will have 0.But in case of big-endian 1 will be store at the right
    > most bye so right shifting by 1 should not be obtain 0. Is my
    > understanding correct?


    No. When x is unsigned (or signed and non-negative) x >> 1 is defined
    to be the integer part of x/2. In effect, the shift operates on the
    value bits in their value order.

    > I did not have access to big-endian machine. So i have not checked the
    > program in big-endian machine.


    --
    Ben.
     
    Ben Bacarisse, Feb 20, 2012
    #2
    1. Advertising

  3. somenath

    somenath Guest

    On Feb 20, 4:49 pm, Ben Bacarisse <> wrote:
    > somenath <> writes:
    > > Hello All,
    > > Is the following program can correctly determine the byte order of the
    > > machine?

    >
    > No.  The output is independent of the way in which values are stored.
    >
    > > #include<stdio.h>
    > > int main(void)
    > > {
    > >     unsigned int x =1;
    > >     if ((x>>1) == 0)
    > > printf("little-endian\n");
    > >     else
    > >    printf("Big-endian \n");
    > >     return 0;
    > > }
    > > In my opinion in case of little endian the 1 will be stored at the
    > > last byte of the variable x. so if I shift it 1 byte the variable x
    > > will have 0.But in case of big-endian 1 will  be store at the right
    > > most bye so right shifting by 1 should not be obtain 0. Is my
    > > understanding correct?

    >
    > No.  When x is unsigned (or signed and non-negative) x >> 1 is defined
    > to be the integer part of x/2.  In effect, the shift operates on the
    > value bits in their value order.
    >

    I did not get this point. could you please explain it in more detail
    way?
     
    somenath, Feb 20, 2012
    #3
  4. "somenath" <> schrieb im Newsbeitrag
    news:...
    > Hello All,
    > Is the following program can correctly determine the byte order of the
    > machine?
    > #include<stdio.h>
    > int main(void)
    > {
    > unsigned int x =1;
    > if ((x>>1) == 0)
    > printf("little-endian\n");
    > else
    > printf("Big-endian \n");
    > return 0;
    > }
    > In my opinion in case of little endian the 1 will be stored at the
    > last byte of the variable x. so if I shift it 1 byte the variable x
    > will have 0.But in case of big-endian 1 will be store at the right
    > most bye so right shifting by 1 should not be obtain 0. Is my
    > understanding correct?
    > I did not have access to big-endian machine. So i have not checked the
    > program in big-endian machine.
    >
    > Thanks.
    > Somenath


    Hi,

    x >> 1 is always x / 2, that does not depend on the byte order. Try e.g.
    this instead (untested):

    #include <stdio.h>
    int main(void)
    {
    typedef unsigned char t_b[2];
    union {
    t_b b;
    unsigned short s;
    } u;
    u.s = 1;
    if (u.b[0] == 1)
    // u.b[1] == 0
    printf("little-endian\n");
    else
    // u.b[0] == 0
    // u.b[1] == 1
    printf("big-endian\n");
    return 0;
    }

    Heiner
     
    Heinrich Wolf, Feb 20, 2012
    #4
  5. ....
    > x >> 1 is always x / 2,

    I'm sorry - not always, but normally under the condition, that Ben wrote
    ....
     
    Heinrich Wolf, Feb 20, 2012
    #5
  6. "somenath" <> schrieb im Newsbeitrag
    news:...
    ....
    > No. When x is unsigned (or signed and non-negative) x >> 1 is defined
    > to be the integer part of x/2. In effect, the shift operates on the
    > value bits in their value order.
    >

    I did not get this point. could you please explain it in more detail
    way?

    An example:
    0x04030201
    on a big endian machine is
    0x04 0x03 0x02 0x01,
    on a little endian machine is
    0x01 0x02 0x03 0x04

    0x04030201 >> 1 is 0x02018100
    That is
    0x02 0x01 0x81 0x00
    on a big endian machine and
    0x00 0x81 0x01 0x02
    on a little endian machine.
     
    Heinrich Wolf, Feb 20, 2012
    #6
  7. somenath

    James Kuyper Guest

    On 02/20/2012 06:35 AM, somenath wrote:
    > Hello All,
    > Is the following program can correctly determine the byte order of the
    > machine?
    > #include<stdio.h>
    > int main(void)
    > {
    > unsigned int x =1;
    > if ((x>>1) == 0)
    > printf("little-endian\n");
    > else
    > printf("Big-endian \n");
    > return 0;
    > }


    The expression E1 >> E2 has a value defined by the standard only for
    non-negative x and non-negative values of E2 that are less than the
    width of the type. When that is the case, the behavior defined by the
    standard depends only upon the values of E1 and E2, and not on the way
    that they are represented. Is is simply E1 / (2^E2); in this particular
    case, that works out to 1/2, which is 0 according to C's rules for
    integer division. The value of the result tells you nothing about the
    byte order of unsigned int.
    --
    James Kuyper
     
    James Kuyper, Feb 20, 2012
    #7
  8. somenath

    James Kuyper Guest

    On 02/20/2012 07:11 AM, somenath wrote:
    > On Feb 20, 4:49�pm, Ben Bacarisse <> wrote:
    >> somenath <> writes:
    >>> Hello All,
    >>> Is the following program can correctly determine the byte order of the
    >>> machine?

    >>
    >> No. �The output is independent of the way in which values are stored.
    >>
    >>> #include<stdio.h>
    >>> int main(void)
    >>> {
    >>> � � unsigned int x =1;
    >>> � � if ((x>>1) == 0)
    >>> printf("little-endian\n");
    >>> � � else
    >>> � �printf("Big-endian \n");
    >>> � � return 0;
    >>> }
    >>> In my opinion in case of little endian the 1 will be stored at the
    >>> last byte of the variable x. so if I shift it 1 byte the variable x
    >>> will have 0.But in case of big-endian 1 will �be store at the right
    >>> most bye so right shifting by 1 should not be obtain 0. Is my
    >>> understanding correct?

    >>
    >> No. �When x is unsigned (or signed and non-negative) x >> 1 is defined
    >> to be the integer part of x/2. �In effect, the shift operates on the
    >> value bits in their value order.
    >>

    > I did not get this point. could you please explain it in more detail
    > way?


    Let's keep it simple, by considering an implementation where
    CHAR_BIT==8, and UINT_MAX is 65535. The bits that make up an unsigned
    int therefore represent the values 1, 2, 4, 8, 16, 32, 64, 128, 256,
    512, 1024, 2048, 4096, 8192, 16384. Let's assume that the first 8 of
    those bits are stored in the one byte, and the remaining 8 are stored in
    the other one, without bothering to identify which order those bytes are
    in. Whatever the value stored in x is, the expression x >> 1 produces a
    result that would correspond to taking the value of the bit that
    represents 2, and moving it into the bit that represents 1; moving the
    value of the bit that represents 4, into the bit that represents 2; etc.

    The interesting case is the bit representing 256, the value of which
    must be moved into the bit which represents 128, which is in a different
    byte. Here's the important point - it must be moved into that bit,
    regardles of whether the byte containing that bit occurs before or after
    the byte containing the bit representing 256 in memory. The "right" in
    "right shift" refers only the to values of the bits, it has nothing to
    do with the order of the bytes containing those bits in memory.

    Another key point: the value of the bit that represents 1 simply
    disappears - it does not get moved into the bit representing 16384 (that
    would be called a rotation, rather than a shift), nor does it get moved
    anywhere else. The bit representing 16384 simply gets set to 0.
    --
    James Kuyper
     
    James Kuyper, Feb 20, 2012
    #8
  9. somenath

    Noob Guest

    somenath wrote:

    > #include<stdio.h>
    > int main(void)
    > {
    > unsigned int x =1;
    > if ((x>>1) == 0)


    1U >> 1 equals 0 on every C platform in the universe.

    Consider

    unsigned int x = 1;
    unsigned char arr[sizeof x];
    memcpy(arr, &x, sizeof x);
     
    Noob, Feb 20, 2012
    #9
  10. somenath

    Eric Sosman Guest

    On 2/20/2012 6:35 AM, somenath wrote:
    > Hello All,
    > Is the following program can correctly determine the byte order of the
    > machine?


    No.

    > #include<stdio.h>
    > int main(void)
    > {
    > unsigned int x =1;
    > if ((x>>1) == 0)
    > printf("little-endian\n");
    > else
    > printf("Big-endian \n");
    > return 0;
    > }


    This code will print "little-endian\n" on all systems (barring
    I/O errors and the like).

    > In my opinion in case of little endian the 1 will be stored at the
    > last byte of the variable x. so if I shift it 1 byte the variable x
    > will have 0.But in case of big-endian 1 will be store at the right
    > most bye so right shifting by 1 should not be obtain 0. Is my
    > understanding correct?


    No. For one thing, your explanations of little-endian and
    big-endian seem rather confused; what do you mean, precisely, by
    "last" and "right most?"

    Even when the confusion is cleared up, you're missing the fact
    that the `>>' operator (like most C operators) works with the values
    of its operands, not with their representations. The `>>' operator
    is most easily described in terms of a binary representation of its
    first operand, and "right" shift suggests a certain way of writing
    that representation -- but that doesn't mean the hardware actually
    rolls bits around like so many tiny marbles. The bit that is discarded
    by `>> 1' is the *least significant* bit, which in your example is
    always 1 beforehand and 0 afterward.

    > I did not have access to big-endian machine. So i have not checked the
    > program in big-endian machine.


    You should also be aware that "big-endian" and "little-endian"
    do not exhaust all the possibilities. There have been "middle-endian"
    machines, and "no-endian" CPU's are said to be fairly common among
    digital signal processors and perhaps some supercomputers.

    C requires that its unsigned integers behave "as if" written in
    base 2 positional notation, with a 1's bit, 2's bit, 4's bit, and so
    on. However, C says nothing at all about the arrangement of those
    bits! For example, there is no rule requiring the 1's bit and the
    2's bit to occupy the same byte of a multi-byte integer (it would
    be perverse if they did not, but C tolerates perversity).

    Your best bet is to write code that works with values, regardless
    of how those values are represented. Ideally, you would not even
    know how the machine represents eight hundred seventeen; you should
    concern yourself with finding its factors or comparing it to nine
    hundred twenty-six or whatever. It is occasionally necessary to
    pierce the veil, but not very often.

    --
    Eric Sosman
    d
     
    Eric Sosman, Feb 20, 2012
    #10
  11. somenath

    BartC Guest

    "somenath" <> wrote in message
    news:...

    > Is the following program can correctly determine the byte order of the
    > machine?


    I tried this:

    char bytes[2]={1,2};

    printf("%2X\n",*((short*)bytes));

    On my machine, it printed 201, as I expected where the least-significant
    byte occurs first in memory.

    But I also knew that chars were 8 bits, and shorts were 16 bits. I think
    also on some machines, the two 16-bit halves of a 32-bit value may be
    mangled in some way (68000?).

    --
    Bartc
     
    BartC, Feb 20, 2012
    #11
  12. somenath

    BartC Guest

    "somenath" <> wrote in message
    news:...

    > Is the following program can correctly determine the byte order of the
    > machine?


    I tried this:

    char bytes[2]={1,2};
    printf("%2X\n",*((short*)bytes));

    On my machine, it printed 201, as I expected where the least-significant
    byte occurs first in memory.

    I also tried:

    char bytes[4]={1,2,3,4};
    printf("%4X\n",*((int*)bytes));

    And got 4030201, again as expected. However I knew my machine uses 8, 16 and
    32-bit widths for char, short and int.

    Other machines may give unexpected results, for example some mangled form of
    {1,2,3,4} instead of 4030201 or 1020304 (68000?).

    --
    Bartc
     
    BartC, Feb 20, 2012
    #12
  13. BartC wrote:
    > "somenath" <> wrote in message
    > news:...
    >
    >> Is the following program can correctly determine the byte order of
    >> the machine?

    >
    > I tried this:
    >
    > char bytes[2]={1,2};
    >
    > printf("%2X\n",*((short*)bytes));
    >
    > On my machine, it printed 201, as I expected where the
    > least-significant byte occurs first in memory.
    >
    > But I also knew that chars were 8 bits, and shorts were 16 bits. I
    > think also on some machines, the two 16-bit halves of a 32-bit value
    > may be mangled in some way (68000?).


    m68k is big endian
     
    Joachim Schmitz, Feb 20, 2012
    #13
  14. somenath <> writes:

    > On Feb 20, 4:49 pm, Ben Bacarisse <> wrote:
    >> somenath <> writes:
    >> > Hello All,
    >> > Is the following program can correctly determine the byte order of the
    >> > machine?

    >>
    >> No.  The output is independent of the way in which values are stored.
    >>
    >> > #include<stdio.h>
    >> > int main(void)
    >> > {
    >> >     unsigned int x =1;
    >> >     if ((x>>1) == 0)
    >> > printf("little-endian\n");
    >> >     else
    >> >    printf("Big-endian \n");
    >> >     return 0;
    >> > }
    >> > In my opinion in case of little endian the 1 will be stored at the
    >> > last byte of the variable x. so if I shift it 1 byte the variable x
    >> > will have 0.But in case of big-endian 1 will  be store at the right
    >> > most bye so right shifting by 1 should not be obtain 0. Is my
    >> > understanding correct?

    >>
    >> No.  When x is unsigned (or signed and non-negative) x >> 1 is defined
    >> to be the integer part of x/2.  In effect, the shift operates on the
    >> value bits in their value order.
    >>

    > I did not get this point. could you please explain it in more detail
    > way?


    It's hard to do that. x >> 1 is simply defined to be the same as x/2.
    I am sure that you agree that dividing an unsigned x by 2 (in the C
    sense that does integer division) does not in any way depend on the way
    the bytes are stored in the machine. x/2 is the same on all machines.
    Similarly, x >> 1 is the same on all machines.

    Now with signed ints things are a little more complex because the C
    standard leave a few more things open for the compiler to decide, but
    even there the basic operation is the same. >> moves high-order bits
    into lower-order positions and << does the reverse. It does not matter
    where or how these bits are stored, the effect is the same. 1 << 1 is 2
    on all machines, and 4 >> 2 is 1 on all machines.

    --
    Ben.
     
    Ben Bacarisse, Feb 20, 2012
    #14
  15. somenath

    BartC Guest

    "Joachim Schmitz" <> wrote in message
    news:jhtm6m$jpk$...
    > BartC wrote:


    >> But I also knew that chars were 8 bits, and shorts were 16 bits. I
    >> think also on some machines, the two 16-bit halves of a 32-bit value
    >> may be mangled in some way (68000?).

    >
    > m68k is big endian


    I was probably thinking of something else where the representation was not
    straightforward.

    But even on the 68K, which had 16-bit-wide (8-bit accessible) memory, the
    number 0xBBAA would be stored, I think, as (BBAA) or (BB,AA) byte addressed,
    but 0xDDCCBBAA would be stored as (BBAA,DDCC), or (BB,AA,DD,CC) byte
    addressed.

    Whether I'm right or wrong, it makes me glad I'm working with x86
    byte-addressed little-endian, which doesn't do my head in so much..

    --
    Bartc
     
    BartC, Feb 20, 2012
    #15
  16. somenath

    Noob Guest

    BartC wrote:

    > I was probably thinking of something else where the representation was not
    > straightforward.
    >
    > But even on the 68K, which had 16-bit-wide (8-bit accessible) memory, the
    > number 0xBBAA would be stored, I think, as (BBAA) or (BB,AA) byte addressed,
    > but 0xDDCCBBAA would be stored as (BBAA,DDCC), or (BB,AA,DD,CC) byte
    > addressed.


    Are you thinking of middle-endian (or mixed-endian) as seen on the PDP-11?
    http://en.wikipedia.org/wiki/Endianness#Middle-endian
     
    Noob, Feb 20, 2012
    #16
  17. BartC wrote:
    > "Joachim Schmitz" <> wrote in message
    > news:jhtm6m$jpk$...
    >> BartC wrote:

    >
    >>> But I also knew that chars were 8 bits, and shorts were 16 bits. I
    >>> think also on some machines, the two 16-bit halves of a 32-bit value
    >>> may be mangled in some way (68000?).

    >>
    >> m68k is big endian

    >
    > I was probably thinking of something else where the representation
    > was not straightforward.
    >
    > But even on the 68K, which had 16-bit-wide (8-bit accessible) memory,
    > the number 0xBBAA would be stored, I think, as (BBAA) or (BB,AA) byte
    > addressed, but 0xDDCCBBAA would be stored as (BBAA,DDCC), or
    > (BB,AA,DD,CC) byte addressed.


    I believe m68k is 32 bit.

    > Whether I'm right or wrong, it makes me glad I'm working with x86
    > byte-addressed little-endian, which doesn't do my head in so much..
     
    Joachim Schmitz, Feb 20, 2012
    #17
  18. somenath

    Nils M Holm Guest

    Noob <root@127.0.0.1> wrote:
    > Are you thinking of middle-endian (or mixed-endian) as seen on the PDP-11?
    > http://en.wikipedia.org/wiki/Endianness#Middle-endian


    Note, though, that this is merely a convention used by the compiler
    in this case, as the 11 has no 32-bit store instructions.

    --
    Nils M Holm < n m h @ t 3 x . o r g > www.t3x.org
     
    Nils M Holm, Feb 20, 2012
    #18
  19. somenath

    somenath Guest

    On Feb 20, 7:52 pm, Ben Bacarisse <> wrote:
    > somenath <> writes:
    > > On Feb 20, 4:49 pm, Ben Bacarisse <> wrote:
    > >> somenath <> writes:
    > >> > Hello All,
    > >> > Is the following program can correctly determine the byte order of the
    > >> > machine?

    >
    > >> No.  The output is independent of the way in which values are stored..

    >
    > >> > #include<stdio.h>
    > >> > int main(void)
    > >> > {
    > >> >     unsigned int x =1;
    > >> >     if ((x>>1) == 0)
    > >> > printf("little-endian\n");
    > >> >     else
    > >> >    printf("Big-endian \n");
    > >> >     return 0;
    > >> > }
    > >> > In my opinion in case of little endian the 1 will be stored at the
    > >> > last byte of the variable x. so if I shift it 1 byte the variable x
    > >> > will have 0.But in case of big-endian 1 will  be store at the right
    > >> > most bye so right shifting by 1 should not be obtain 0. Is my
    > >> > understanding correct?

    >
    > >> No.  When x is unsigned (or signed and non-negative) x >> 1 is defined
    > >> to be the integer part of x/2.  In effect, the shift operates on the
    > >> value bits in their value order.

    >
    > > I did not get this point. could you please explain it in more detail
    > > way?

    >
    > It's hard to do that.  x >> 1 is simply defined to be the same as x/2.
    > I am sure that you agree that dividing an unsigned x by 2 (in the C
    > sense that does integer division) does not in any way depend on the way
    > the bytes are stored in the machine.  x/2 is the same on all machines.
    > Similarly, x >> 1 is the same on all machines.
    >
    > Now with signed ints things are a little more complex because the C
    > standard leave a few more things open for the compiler to decide, but
    > even there the basic operation is the same.  >> moves high-order bits
    > into lower-order positions and << does the reverse.  It does not matter
    > where or how these bits are stored, the effect is the same.  1 << 1 is 2
    > on all machines, and 4 >> 2 is 1 on all machines.
    >


    Thanks all for the explanation.
    Actually I forgot the fact that the LSB or MSB of any byte never
    depends on the the way bits are laid. LSB is always the 0th bit. The
    0th bit may reside on address A or it may reside on A+32. So if int x
    =1; x>>1 will always clear the LSB irrespective of the fact it is laid
    over address.
     
    somenath, Feb 20, 2012
    #19
  20. somenath

    Joe Pfeiffer Guest

    somenath <> writes:

    > Hello All,
    > Is the following program can correctly determine the byte order of the
    > machine?
    > #include<stdio.h>
    > int main(void)
    > {
    > unsigned int x =1;
    > if ((x>>1) == 0)
    > printf("little-endian\n");
    > else
    > printf("Big-endian \n");
    > return 0;
    > }
    > In my opinion in case of little endian the 1 will be stored at the
    > last byte of the variable x. so if I shift it 1 byte the variable x
    > will have 0.But in case of big-endian 1 will be store at the right
    > most bye so right shifting by 1 should not be obtain 0. Is my
    > understanding correct?


    No, there are at least two different misunderstandings underlying your
    code:

    (1) shifts work across the entire int, no matter what order the bytes of
    the int appear in, in the underlying machine. So a shift by one
    byte will result in an 8-bit shift across the entire word; it'll
    give the same result whether the machine is big-endian or
    little-endian.

    (2) you aren't shifting by a byte, you're shifting by a bit. If it
    weren't for the first misunderstanding your code would detect the
    difference anyway, but it still wouldn't be doing what you expect.

    If I wanted to check whether a machine were big-endian or little-endian,
    my first choice would be to see whether the htonl macro (which converts
    a host-order long to a network-order long, which we know in turn is
    defined to be big-endian) changes anything. I expect that macro is
    outside the scope of this newsgroup, since I'd be surprised if it were
    part of the C standard.

    You could also (on a machine with 8-bit bytes) declare an array of 4
    chars, cast the array to a long and assign a value to it, then print the
    values of the eight chars.

    But, ummm... if the goal is really just to find out the answer, why not
    look in an architecture manual for the machine?
     
    Joe Pfeiffer, Feb 20, 2012
    #20
    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. Andreas
    Replies:
    1
    Views:
    881
    Jonathan Bromley
    May 4, 2004
  2. Bharat Bhushan

    Appending byte[] to another byte[] array

    Bharat Bhushan, Aug 5, 2003, in forum: Java
    Replies:
    15
    Views:
    40,326
    Roedy Green
    Aug 5, 2003
  3. Jean-Daniel Gamache
    Replies:
    0
    Views:
    431
    Jean-Daniel Gamache
    Jul 14, 2004
  4. Peña, Botp
    Replies:
    1
    Views:
    246
    Robert Klemme
    Jan 24, 2004
  5. Robert Evans
    Replies:
    7
    Views:
    321
    Joel VanderWerf
    Nov 15, 2005
Loading...

Share This Page