Thread: Fiddling with the bits(Big Endian vs Little Endian)

  1. #1
    Registered User
    Join Date
    Sep 2006
    Location
    Beaverton, Oregon, United States
    Posts
    176

    Fiddling with the bits(Big Endian vs Little Endian)

    Code:
    int int_size(void)
    {
    unsigned int bits;
    int size=0;
    
    bits=~0;
    
    while(bits)
    {
        size++;
        bits>>=1;
    }
    
    return size;
    }
    This is one of the ways recommended to me to determine bit size on any processor. What I would like to know is how can I also determine big endian or little endian? Is there any easy way to do that? I could kill two birds with one stone as I plan on converting this to an m68k processor which I believe is little endian. But even if its not I'm still curious as how to determine endianness on different processors.

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    If you want to know how many bits are in some type, simply get the size of that type in bytes (using sizeof operator), and multiply by the number of bits in a byte. So you could do:
    Code:
    #define INT_SIZE_IN_BITS    (sizeof(int) * CHAR_BIT)
    That is better, since it's determined at compile time, and doesn't cost any CPU cycles and is portable. The number of bits in an int is a constant for any given architecture, so there is no need to compute it run-time.

    As for checking for endianness, you can't get a two-for-one deal here, you need a different mechanism. Try Google: https://www.google.com/search?q=c+determine+endianness.

  3. #3
    Registered User
    Join Date
    Sep 2006
    Location
    Beaverton, Oregon, United States
    Posts
    176
    dig some digging around, think I found something.
    Code:
    int num = 1;
    if(*(char *)&num == 1)
    {
        printf("\nLittle-Endian\n");
    }
    else
    {
        printf("Big-Endian\n");
    }
    I gotta admit that pointer calls like this leave me scratching my head a little:

    Code:
    if(*(char *)&num == 1)

  4. #4
    Registered User
    Join Date
    Sep 2006
    Location
    Beaverton, Oregon, United States
    Posts
    176
    Quote Originally Posted by anduril462 View Post
    If you want to know how many bits are in some type, simply get the size of that type in bytes (using sizeof operator), and multiply by the number of bits in a byte. So you could do:
    Code:
    #define INT_SIZE_IN_BITS    (sizeof(int) * CHAR_BIT)
    That is better, since it's determined at compile time, and doesn't cost any CPU cycles and is portable. The number of bits in an int is a constant for any given architecture, so there is no need to compute it run-time.

    As for checking for endianness, you can't get a two-for-one deal here, you need a different mechanism. Try Google: https://www.google.com/search?q=c+determine+endianness.
    sorry about that, you posted so quick I didnt even catch it! Thanks!!

  5. #5
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    num is of type 'int'
    &num is the address of num, which is of type 'pointer to int'
    (char *)&num casts the pointer to int, to type 'pointer to char'
    *(char *)&num takes that pointer to char, and dereferences it to a plain char

    That works because an int is more than one byte. We'll assume 4 bytes for this example. It starts at (for example) address 0x1000, and goes through 0x1003. When you set that int to 1, you set the least significant bit to 1, which (depending on the endianness) will be either in the byte at 0x1000 (little endian) or 0x1003 (big endian). So:
    Code:
    // big endian
    0x1000     0000 0000
    0x1001     0000 0000
    0x1002     0000 0000
    0x1003     0000 0001
    
    // little endian
    0x1000     0000 0001
    0x1001     0000 0000
    0x1002     0000 0000
    0x1003     0000 0000
    Now, the address of num will always be it's "starting" address, i.e. the lowest address, or 0x1000. Cast that to a char, and you still get address 0x1000. But when you dereference it, you only get one byte, the byte at 0x1000 (not the rest of them), because a char is one byte. Thus, if that one byte at 0x1000 is a 1, it's little endian, if not it's big endian*.

    * There are also mixed/middle endian architectures out there, but they're not so common any more. Also, some architectures, like ARM, can be configured for big or little endian.

  6. #6
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by A34Chris View Post
    sorry about that, you posted so quick I didnt even catch it! Thanks!!
    No worries. To follow up with that, technically CHAR_BIT may be something other than 8, but I'm aware of no such architectures where that is the case. Best to use it though, for portability and clarity.

  7. #7
    Registered User
    Join Date
    Sep 2006
    Location
    Beaverton, Oregon, United States
    Posts
    176
    Thank you very much for all this help. I really appreciate it! I hope someone else can also learn something from all this work you put into explaining this.

  8. #8
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    948
    The Motorola 68000 is big endian. But you could've found that out once you ported your code to it.

  9. #9
    Registered User
    Join Date
    Sep 2006
    Location
    Beaverton, Oregon, United States
    Posts
    176
    Quote Originally Posted by christop View Post
    The Motorola 68000 is big endian. But you could've found that out once you ported your code to it.
    spoiler!!

  10. #10
    Registered User
    Join Date
    Oct 2012
    Posts
    99
    Cool - my comp is little endian. But someone want to give 1 sentance as to what the main advantage or disadvantages are of big/little endian? Years ago, I had to figure this out for a program I was writing and now can't remember the details of it.......

  11. #11
    Registered User
    Join Date
    Sep 2008
    Location
    Toronto, Canada
    Posts
    1,834
    That's a good question. Apart from how the CPU is wired as to how it aggregates bytes to make larger integers... there isn't a difference performance wise. I believe in the Intel family you can set it up to do either endian - in some status/supervisory register. Plus there are machine instructions to shuffle bytes... but not readily acessible in native C.

    The endian issue rarely manifests itself as a problem unless you are slapping integers out to an external file, and reading this file into another platform. Or you are transmitting bytes in some order through a serial port.

    Don't forget that for the sake of completeness, there is also "mixed endian" where in a 32-bit integer for example, 16-bit words may be reversed, yet their bytes are not. Or the other way. And who knows what byte order the machine decides to store floating point numbers.
    Last edited by nonoob; 10-19-2012 at 02:28 PM.

  12. #12
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by gratiafide View Post
    Cool - my comp is little endian. But someone want to give 1 sentance as to what the main advantage or disadvantages are of big/little endian? Years ago, I had to figure this out for a program I was writing and now can't remember the details of it.......
    A brief discussion of the tradeoffs of big and little endian: Endianness - Wikipedia, the free encyclopedia.

    Quote Originally Posted by nonoob View Post
    That's a good question. Apart from how the CPU is wired as to how it aggregates bytes to make larger integers... there isn't a difference performance wise. I believe in the Intel family you can set it up to do either endian - in some status/supervisory register. Plus there are machine instructions to shuffle bytes... but not readily acessible in native C.
    According to Wikipedia, x86 and x86-64 are little endian, but IA-64 could be either.

  13. #13
    Registered User
    Join Date
    Sep 2006
    Location
    Beaverton, Oregon, United States
    Posts
    176
    [B]Now, the address of num will always be it's "starting" address, i.e. the lowest address, or 0x1000. Cast that to a char, and you still get address 0x1000. But when you dereference it, you only get one byte, the byte at 0x1000 (not the rest of them), because a char is one byte. Thus, if that one byte at 0x1000 is a 1, it's little endian, if not it's big endian*.
    ok right, because pointers start with the first memory address and read only that address unless incremented. Clever. This is a beautiful explanation. Thanks again.

  14. #14
    Registered User
    Join Date
    Sep 2006
    Location
    Beaverton, Oregon, United States
    Posts
    176
    Quote Originally Posted by christop View Post
    The Motorola 68000 is big endian. But you could've found that out once you ported your code to it.
    Whoops did something wrong then. Its saying Little-Endian. But its running under emulation.
    Last edited by A34Chris; 10-21-2012 at 07:12 PM.

  15. #15
    Registered User
    Join Date
    Sep 2006
    Location
    Beaverton, Oregon, United States
    Posts
    176
    Quote Originally Posted by A34Chris View Post
    Code:
    int int_size(void)
    {
    unsigned int bits;
    int size=0;
    
    bits=~0;
    
    while(bits)
    {
        size++;
        bits>>=1;
    }
    
    return size;
    }
    This is one of the ways recommended to me to determine bit size on any processor. What I would like to know is how can I also determine big endian or little endian? Is there any easy way to do that? I could kill two birds with one stone as I plan on converting this to an m68k processor which I believe is little endian. But even if its not I'm still curious as how to determine endianness on different processors.
    In regards to this program snippet here, it should matter which way the bits are shifted depending on the Endianness shouldn''t it? Kochans 'Programming in C' doesn't really touch on that. Or whether that pointers to bits always start at the lease significant bit or whether they always start at the right or the left regardless of Endianness. I guess certain things are assumed to be understood.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Little endian and Bit endian advantages and disadvantages
    By nkrao123@gmail. in forum C Programming
    Replies: 4
    Last Post: 09-11-2011, 04:40 AM
  2. Little vs Big Endian
    By Wokzombie in forum Tech Board
    Replies: 7
    Last Post: 09-11-2010, 11:46 AM
  3. big endian-small endian problem
    By kapil1089thekin in forum C Programming
    Replies: 3
    Last Post: 05-15-2008, 06:47 PM
  4. Big Endian Little Endian Complex- Converting Characters
    By bd02eagle in forum C Programming
    Replies: 3
    Last Post: 07-11-2006, 01:01 AM
  5. Big endian/Little endian conversion
    By bonkey in forum Windows Programming
    Replies: 5
    Last Post: 09-25-2002, 02:29 PM