<p>What is the difference between the following types of endianness?</p>

<ul>
<li>byte (8b) invariant big and little endianness</li>
<li>half-word (16b) invariant big and little endianness</li>
<li>word (32b) invariant big and little endianness</li>
<li>double-word (64b) invariant big and little endianness</li>
</ul>

<p>Are there other types/variations?</p>

[{'answer_id': 21455, 'author': 'James A. Rosen', 'author_id': 1190, 'author_profile': 'https://Stackoverflow.com/users/1190', 'pm_score': -1, 'selected': False, 'text': '<p>the basic concept is the ordering of bits:</p>\n\n<pre><code>1010 0011\n</code></pre>\n\n<p>in little-endian is the same as</p>\n\n<pre><code>0011 1010\n</code></pre>\n\n<p>in big-endian (and vice-versa).</p>\n\n<p>You\'ll notice the order changes by grouping, not by individual bit.  I don\'t know of a system, for example, where</p>\n\n<pre><code>1100 0101\n</code></pre>\n\n<p>would be the "other-endian" version of the first version.</p>\n'}, {'answer_id': 21470, 'author': 'Erik van Brakel', 'author_id': 909, 'author_profile': 'https://Stackoverflow.com/users/909', 'pm_score': 2, 'selected': False, 'text': '<p>There\'s also middle or mixed endian. See <a href="http://en.wikipedia.org/wiki/Middle_endian#Middle-endian" rel="nofollow noreferrer">wikipedia</a> for details.</p>\n\n<p>The only time I had to worry about this was when writing some networking code in C. Networking typically uses big-endian IIRC. Most languages either abstract the whole thing or offer libraries to guarantee that you\'re using the right endian-ness though.</p>\n'}, {'answer_id': 21531, 'author': 'dguaraglia', 'author_id': 2384, 'author_profile': 'https://Stackoverflow.com/users/2384', 'pm_score': 1, 'selected': False, 'text': '<p>Actually, I\'d describe the endianness of a machine as the order of <strong>bytes</strong> inside of a word, and not the order of <strong>bits</strong>.</p>\n\n<p>By "bytes" up there I mean the "smallest unit of memory the architecture can manage individually". So, if the smallest unit is 16 bits long (what in x86 would be called a <em>word</em>) then a 32 bit "word" representing the value 0xFFFF0000 could be stored like this:</p>\n\n<pre><code>FFFF 0000\n</code></pre>\n\n<p>or this:</p>\n\n<pre><code>0000 FFFF\n</code></pre>\n\n<p>in memory, depending on endianness.</p>\n\n<p>So, if you have 8-bit endianness, it means that every word consisting of 16 bits, will be stored as:</p>\n\n<pre><code>FF 00\n</code></pre>\n\n<p>or:</p>\n\n<pre><code>00 FF\n</code></pre>\n\n<p>and so on.</p>\n'}, {'answer_id': 21624, 'author': 'jfs', 'author_id': 718, 'author_profile': 'https://Stackoverflow.com/users/718', 'pm_score': 2, 'selected': False, 'text': '<p>Best article I read about endianness "<a href="http://betterexplained.com/articles/understanding-big-and-little-endian-byte-order/" rel="nofollow noreferrer">Understanding Big and Little Endian Byte Order</a>".</p>\n'}, {'answer_id': 61730, 'author': 'Ben Lever', 'author_id': 2045, 'author_profile': 'https://Stackoverflow.com/users/2045', 'pm_score': 5, 'selected': False, 'text': '<p>There are two approaches to endian mapping: <em>address invariance</em> and <em>data invariance</em>.</p>\n\n<h2>Address Invariance</h2>\n\n<p>In this type of mapping, the address of bytes is always preserved between big and little. This has the side effect of reversing the order of significance (most significant to least significant) of a particular datum (e.g. 2 or 4 byte word) and therefore the interpretation of data. Specifically, in little-endian, the interpretation of data is least-significant to most-significant bytes whilst in big-endian, the interpretation is most-significant to least-significant. In both cases, the set of bytes accessed remains the same.</p>\n\n<p><strong>Example</strong></p>\n\n<p>Address invariance (also known as <em>byte invariance</em>): the byte address is constant but byte significance is reversed.</p>\n\n<pre><code>Addr   Memory\n       7    0\n       |    |    (LE)   (BE)\n       |----|\n +0    | aa |    lsb    msb\n       |----|\n +1    | bb |     :      :\n       |----|\n +2    | cc |     :      :\n       |----|\n +3    | dd |    msb    lsb\n       |----|\n       |    |\n\nAt Addr=0:          Little-endian          Big-endian\nRead 1 byte:              0xaa                0xaa   (preserved)\nRead 2 bytes:           0xbbaa              0xaabb\nRead 4 bytes:       0xddccbbaa          0xaabbccdd\n</code></pre>\n\n<h2>Data Invariance</h2>\n\n<p>In this type of mapping, the relative byte significance is preserved for datum of a particular size. There are therefore different types of data invariant endian mappings for different datum sizes. For example, a 32-bit word invariant endian mapping would be used for a datum size of 32. The effect of preserving the value of particular sized datum, is that the byte addresses of bytes within the datum are reversed between big and little endian mappings.</p>\n\n<p><strong>Example</strong></p>\n\n<p>32-bit data invariance (also known as <em>word invariance</em>): The datum is a 32-bit word which always has the value <code>0xddccbbaa</code>, independent of endianness. However, for accesses smaller than a word, the address of the bytes are reversed between big and little endian mappings.</p>\n\n<pre><code>Addr                Memory\n\n            | +3   +2   +1   +0 |  &lt;- LE\n            |-------------------|\n+0      msb | dd | cc | bb | aa |  lsb\n            |-------------------|\n+4      msb | 99 | 88 | 77 | 66 |  lsb\n            |-------------------|\n     BE -&gt;  | +0   +1   +2   +3 |\n\n\nAt Addr=0:             Little-endian              Big-endian\nRead 1 byte:                 0xaa                    0xdd\nRead 2 bytes:              0xbbaa                  0xddcc\nRead 4 bytes:          0xddccbbaa              0xddccbbaa   (preserved)\nRead 8 bytes:  0x99887766ddccbbaa      0x99887766ddccbbaa   (preserved)\n</code></pre>\n\n<p><strong>Example</strong></p>\n\n<p>16-bit data invariance (also known as <em>half-word invariance</em>): The datum is a 16-bit\nwhich always has the value <code>0xbbaa</code>, independent of endianness. However, for accesses smaller than a half-word, the address of the bytes are reversed between big and little endian mappings.</p>\n\n<pre><code>Addr           Memory\n\n            | +1   +0 |  &lt;- LE\n            |---------|\n+0      msb | bb | aa |  lsb\n            |---------|\n+2      msb | dd | cc |  lsb\n            |---------|\n+4      msb | 77 | 66 |  lsb\n            |---------|\n+6      msb | 99 | 88 |  lsb\n            |---------|\n     BE -&gt;  | +0   +1 |\n\n\nAt Addr=0:             Little-endian              Big-endian\nRead 1 byte:                 0xaa                    0xbb\nRead 2 bytes:              0xbbaa                  0xbbaa   (preserved)\nRead 4 bytes:          0xddccbbaa              0xddccbbaa   (preserved)\nRead 8 bytes:  0x99887766ddccbbaa      0x99887766ddccbbaa   (preserved)\n</code></pre>\n\n<p><strong>Example</strong></p>\n\n<p>64-bit data invariance (also known as <em>double-word invariance</em>): The datum is a 64-bit\nword which always has the value <code>0x99887766ddccbbaa</code>, independent of endianness. However, for accesses smaller than a double-word, the address of the bytes are reversed between big and little endian mappings.</p>\n\n<pre><code>Addr                         Memory\n\n            | +7   +6   +5   +4   +3   +2   +1   +0 |  &lt;- LE\n            |---------------------------------------|\n+0      msb | 99 | 88 | 77 | 66 | dd | cc | bb | aa |  lsb\n            |---------------------------------------|\n     BE -&gt;  | +0   +1   +2   +3   +4   +5   +6   +7 |\n\n\nAt Addr=0:             Little-endian              Big-endian\nRead 1 byte:                 0xaa                    0x99\nRead 2 bytes:              0xbbaa                  0x9988\nRead 4 bytes:          0xddccbbaa              0x99887766\nRead 8 bytes:  0x99887766ddccbbaa      0x99887766ddccbbaa   (preserved)\n</code></pre>\n'}, {'answer_id': 68689, 'author': 'Benoit', 'author_id': 10703, 'author_profile': 'https://Stackoverflow.com/users/10703', 'pm_score': 1, 'selected': False, 'text': '<p>Practically speaking, endianess refers to the way the processor will interpret the content of a given memory location.  For example, if we have memory location 0x100 with the following content (hex bytes)</p>\n\n<pre><code>\n  0x100:  12 34 56 78 90 ab cd ef\n\nReads    Little Endian            Big Endian\n 8-bit:  12                        12\n16-bit:  34 12                     12 34\n32-bit:  78 56 34 12               12 34 56 78\n64-bit:  ef cd ab 90 78 56 34 12   12 34 56 78 90 ab cd ef\n</code></pre>\n\n<p>The two situations where you need to mind endianess are with networking code and if you do down casting with pointers.</p>\n\n<p>TCP/IP specifies that data on the wire should be big endian. If you transmit types other than byte arrays (like pointers to structures), you should make sure to use the ntoh/hton macros to ensure the data is sent big endian.  If you send from a little-endian processor to a big-endian processor (or vice versa), the data will be garbled...</p>\n\n<p>Casting issues:</p>\n\n<pre><code>\n uint32_t* lptr = 0x100;\n uint16_t  data;\n *lptr = 0x0000FFFF\n\n data = *((uint16_t*)lptr);\n</code></pre>\n\n<p>What will be the value of data?\nOn a big-endian system, it would be 0  On a little-endian system, it would be FFFF</p>\n'}, {'answer_id': 69163, 'author': 'Philibert Perusse', 'author_id': 7984, 'author_profile': 'https://Stackoverflow.com/users/7984', 'pm_score': 0, 'selected': False, 'text': '<p>13 years ago I worked on a tool portable to both a DEC ALPHA system and a PC. On this DEC ALPHA the <strong>bits were actually inverted</strong>. That is:</p>\n\n<pre><code>1010 0011\n</code></pre>\n\n<p>actually translated to</p>\n\n<pre><code>1100 0101\n</code></pre>\n\n<p>It was almost transparent and seamless in the C code except that I had a bitfield declared like</p>\n\n<pre><code>typedef struct {\n   int firstbit:1;\n   int middlebits:10;\n   int lastbits:21;\n};\n</code></pre>\n\n<p>that needed to be translated to (using #ifdef conditional compiling)</p>\n\n<pre><code>typedef struct {\n   int lastbits:21;\n   int middlebits:10;\n   int firstbit:1;\n};\n</code></pre>\n'}, {'answer_id': 3581332, 'author': 'eel ghEEz', 'author_id': 80772, 'author_profile': 'https://Stackoverflow.com/users/80772', 'pm_score': 2, 'selected': False, 'text': '<p><a href="https://stackoverflow.com/questions/21449/types-of-endianness/69163#69163">Philibert</a> said,</p>\n\n<blockquote>\n  <p>bits were actually inverted</p>\n</blockquote>\n\n<p>I doubt any architecture would break byte value invariance.  The order of bit-fields may need inversion when mapping structs containing them against data.  Such direct mapping relies on compiler specifics which are outside the C99 standard but which may still be common.  Direct mapping is faster but does not comply with the C99 standard that does not stipulate packing, alignment and byte order.  C99-compliant code should use slow mapping based on values rather than addresses.  That is, instead of doing this,</p>\n\n<pre><code>#if LITTLE_ENDIAN\n  struct breakdown_t {\n    int least_significant_bit: 1;\n    int middle_bits: 10;\n    int most_significant_bits: 21;\n  };\n#elif BIG_ENDIAN\n  struct breakdown_t {\n    int most_significant_bits: 21;\n    int middle_bits: 10;\n    int least_significant_bit: 1;\n  };\n#else\n  #error Huh\n#endif\n\nuint32_t data = ...;\nstruct breakdown_t *b = (struct breakdown_t *)&amp;data;\n</code></pre>\n\n<p>one should write this (and this is how the compiler would generate code anyways even for the above "direct mapping"),</p>\n\n<pre><code>uint32_t data = ...;\nuint32_t least_significant_bit = data &amp; 0x00000001;\nuint32_t middle_bits = (data &gt;&gt; 1) &amp; 0x000003FF;\nuint32_t most_significant_bits = (data &gt;&gt; 11) &amp; 0x001fffff;\n</code></pre>\n\n<p>The reason behind the need to invert the order of bit-fields in each endian-neutral, application-specific data storage unit is that compilers pack bit-fields into bytes of growing addresses.  </p>\n\n<p>The "order of bits" in each byte does not matter as the only way to extract them is by applying masks of values and by shifting to the the least-significant-bit or most-significant-bit direction.  The "order of bits" issue would only become important in imaginary architectures with the notion of bit addresses.  I believe all existing architectures hide this notion in hardware and provide only least vs. most significant bit extraction which is the notion based on the endian-neutral byte values.</p>\n'}, {'answer_id': 71747967, 'author': 'Meloman', 'author_id': 2282880, 'author_profile': 'https://Stackoverflow.com/users/2282880', 'pm_score': 0, 'selected': False, 'text': '<p>As @erik-van-brakel answered on this post, be careful when communicating with certain PLC : <strong>Mixed-endian still alive !</strong></p>\n<p>Indeed, I need to communicate with a PLC (from a well known manufacturer) with (Modbus-TCP) OPC protocol and it seems that it returns me a mixed-endian on every half word. So it is still used by some of the larger manufacturers.</p>\n<p>Here is an example with the &quot;pieces&quot; string :</p>\n<p><a href="https://i.stack.imgur.com/Pzsdi.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Pzsdi.png" alt="https://i.imgur.com/VrdriAt.png" /></a></p>\n'}]
['https://Stackoverflow.com/questions/21449', 'https://Stackoverflow.com', 'https://Stackoverflow.com/users/2045/']