Intuition What this page is
The parent note taught you the rule : which byte of a multi-byte number lands at the lowest memory address. This page drills every case that rule can throw at you — different value sizes, zeros, sign-bits, strings, mixed-type structs, and the classic exam twists — so you never meet a scenario you haven't already seen worked out.
Before we start, one reminder of the two symbols we lean on the whole way down.
Definition The two words we'll use constantly
MSB — Most Significant Byte : the byte carrying the largest weight. In 0x12345678 that is 0x12 (it multiplies 2 24 ). Think "the leftmost pair of hex digits".
LSB — Least Significant Byte : the byte carrying the smallest weight, 0x78 here (it multiplies 2 0 ). Think "the rightmost pair of hex digits, the ones place".
One hex digit = 4 bits, so two hex digits = one byte = 8 bits . That is why we always chop values into pairs of hex digits.
Endianness looks tiny, but the questions about it fall into distinct cells. Below is every class of case. The worked examples afterwards each tag which cell they cover, and together they fill the whole grid.
Cell
Scenario class
What makes it tricky
C1
Ordinary 4-byte int, both endians
The baseline placement
C2
2-byte (16-bit) value
Smaller N — index range changes
C3
8-byte (64-bit) value
Larger N — bookkeeping stress
C4
Zero value 0x00000000
Degenerate: both endians look identical
C5
Palindromic bytes e.g. 0x12341234? (partial symmetry)
Which bytes actually move?
C6
Value with a 0x00 in the middle / leading zeros
Reading fewer bytes; sign-of-location
C7
Negative int (two's complement, high bit set)
Sign bit lives in the MSB — where does it go?
C8
A char[] string (not a scalar)
Endianness does not apply — the trap
C9
Reading back memory → value (inverse direction)
Reconstruct V from bytes
C10
Cross-endian transmission (network byte order)
Real-world word problem
C11
Type-punning twist : read a 4-byte int as two 2-byte halves
Exam-style; sub-word views
C12
Mixed-type struct laid out in memory
Each field endian-swaps independently; padding
We now walk them all.
Worked example C1 — Store
0x0A0B0C0D (32-bit) at address 200, both endians
Forecast: Before reading on, write down what byte you think sits at address 200 in each convention.
Extract the bytes. Why this step? We must know each byte's significance before we can place it. Using b k = ⌊ V /25 6 k ⌋ mod 256 :
b 0 = 0D , b 1 = 0C , b 2 = 0B , b 3 = 0A
Little-endian, mem [ i ] = b i . Why? LSB-first means the ones-byte goes at the lowest address, so we copy indices straight through:
200 : 0D , 201 : 0C , 202 : 0B , 203 : 0A
Big-endian, mem [ i ] = b 3 − i . Why? MSB-first reverses the index so the biggest byte lands at the smallest address:
200 : 0A , 201 : 0B , 202 : 0C , 203 : 0D
Verify: the big-endian row reads left-to-right exactly like the number 0A 0B 0C 0D, and the little-endian row is its exact reverse. ✓ Look at figure s01 — the same four coloured tiles, poured into the address slots in opposite directions.
Worked example C2 — Store the 16-bit value
0xBEEF at address 10
Forecast: guess the byte at address 10 for each endian.
Now N = 2 , so only indices k = 0 , 1 exist. Why this step? The formula is unchanged, but the index range shrinks — a common slip is to still expect four bytes. b 0 = EF , b 1 = BE .
Little-endian: 10 : EF , 11 : BE .
Big-endian: mem [ i ] = b N − 1 − i = b 1 − i → 10 : BE , 11 : EF .
Verify: reconstruct little-endian: EF ⋅ 25 6 0 + BE ⋅ 25 6 1 = 239 + 190 ⋅ 256 = 48879 = 0xBEEF . ✓ Figure s02 shows this two-tile flip.
Worked example C3 — Store the 64-bit value
0x1122334455667788 at address 0
Forecast: which byte sits at address 7 in little-endian?
N = 8 , indices k = 0..7 . b 0 = 88 , b 1 = 77 , b 2 = 66 , b 3 = 55 , b 4 = 44 , b 5 = 33 , b 6 = 22 , b 7 = 11 . Why? Same extraction, just eight pairs of hex digits.
Little-endian (mem [ i ] = b i ): 0 : 88 , 1 : 77 , 2 : 66 , 3 : 55 , 4 : 44 , 5 : 33 , 6 : 22 , 7 : 11 .
Big-endian (mem [ i ] = b 7 − i ): 0 : 11 , 1 : 22 , … , 7 : 88 .
Verify: little-endian address 7 holds b 7 = 0x11 = the MSB — exactly what "highest address holds the biggest byte" predicts for little-endian. ✓ Figure s03 lines up all eight tiles both ways.
Worked example C4 — The degenerate case: store
0x00000000
Forecast: do the two endians differ here?
All bytes are 0x00: b 0 = b 1 = b 2 = b 3 = 00 . Why this step? When every byte is equal, any permutation of them is identical.
Little-endian: 00 00 00 00. Big-endian: 00 00 00 00.
Verify: the memory images are byte-for-byte equal → endianness is invisible on zero (and on any value whose bytes are all equal, e.g. 0xFFFFFFFF). This is the "both look identical" degenerate cell. ✓
Worked example C5 — Partial symmetry: store
0x12341234
Forecast: which bytes actually change position between the two layouts?
Bytes: b 0 = 34 , b 1 = 12 , b 2 = 34 , b 3 = 12 . Why? Note the pattern repeats every two bytes.
Little-endian: 34 12 34 12 . Big-endian: 12 34 12 34 .
Verify: the two layouts are not equal (unlike C4) — repetition of the 16-bit half is not the full symmetry needed. Full byte-palindromes like 0x12211221? Check: bytes 21 , 12 , 21 , 12 ; LE = 21 12 21 12, BE = 12 21 12 21 — still different. Only all-equal bytes give identical layouts. ✓
Worked example C6 — Leading zeros: store
0x00000005 at 100, then read 1 byte
Forecast: in little-endian, does reading a single byte at 100 give the true value 5?
Bytes: b 0 = 05 , b 1 = b 2 = b 3 = 00 .
Little-endian memory: 100 : 05 , 101 : 00 , 102 : 00 , 103 : 00 . Reading one byte at 100 yields 05. Why this step? The ones-byte lives at the lowest address, so a narrow read already has the low-order data — widening 8→32 bits is "free".
Big-endian memory: 100 : 00 , 101 : 00 , 102 : 00 , 103 : 05 . One byte at 100 yields 00 — you'd have to read address 103.
Verify: little-endian single-byte read = 0x05 = 5 = the value. ✓ Figure s04 highlights the single nonzero tile's location in each layout. This is the practical payoff of low-address-is-low-order.
Worked example C7 — Store the signed 32-bit int
-2 (two's complement)
Forecast: where does the sign bit end up in each endian?
Find the bit pattern. Why this step? Two's complement represents − 2 as 2 32 − 2 = 0xFFFFFFFE . The sign bit is the top bit of the MSB (0xFF, bit pattern 1111 1111).
Bytes: b 0 = FE , b 1 = FF , b 2 = FF , b 3 = FF .
Little-endian: FE FF FF FF — the sign-carrying MSB sits at the highest address.
Big-endian: FF FF FF FE — the sign-carrying MSB sits at the lowest address.
Verify: reconstruct big-endian as an unsigned pattern: FF ⋅ 25 6 3 + FF ⋅ 25 6 2 + FF ⋅ 256 + FE = 4294967294 = 2 32 − 2 , which is − 2 in signed 32-bit. ✓ Endianness never touches the sign interpretation — it only relocates the byte holding the sign bit.
Worked example C8 — Store the string
char s[4] = {'H','e','l','o'}
Forecast: does swapping endianness reorder the letters?
Recognise this is an array of bytes, not one wide scalar. Why this step? Endianness only splits a single multi-byte number . Each char is already exactly one byte, so there is nothing to split.
On both big- and little-endian machines: A : ’H’ , A + 1 : ’e’ , A + 2 : ’l’ , A + 3 : ’o’ .
Verify: ASCII codes H=0x48,e=0x65,l=0x6C,o=0x6F appear in the same address order regardless of endianness. ✓ (The trap: people expect 'o','l','e','H' on little-endian — wrong; array element order is fixed.)
Worked example C9 — Read back memory into a value
Forecast: little-endian bytes 40:AB, 41:CD, 42:34, 43:12 — what 32-bit value is this?
Weight each byte by 25 6 offset because in little-endian the offset equals the byte index k . Why this step? We invert the placement rule mem [ i ] = b i .
V = AB ⋅ 25 6 0 + CD ⋅ 25 6 1 + 34 ⋅ 25 6 2 + 12 ⋅ 25 6 3
Compute: 171 + 205 ⋅ 256 + 52 ⋅ 65536 + 18 ⋅ 16777216 = 171 + 52480 + 3407872 + 301989888 = 305450411 .
Verify: 305450411 = 0x1234CDAB . ✓ Notice the reconstructed hex reads with the highest offset (43) contributing the leftmost digits — that's the little-endian reversal at work.
Worked example C10 — Sending a port number over the network
Forecast: a little-endian laptop must send TCP port 443 in a 16-bit field. Port 443 in memory is mem: bb 01. What two bytes go on the wire, and what would a naive send transmit?
443 in hex is 0x01BB, so b 0 = BB , b 1 = 01 . In the laptop's little-endian memory: mem[0]=BB, mem[1]=01. Why this step? We need the native layout before conversion.
Network byte order is big-endian. The protocol requires MSB first, i.e. 01 BB on the wire. Why? Both ends agreed on big-endian so nobody has to guess the sender's CPU.
A naive send(&port, 2) blasts raw memory = BB 01. The receiver reads big-endian: BB ⋅ 256 + 01 = 47873 — the wrong port. The fix is htons() which byte-swaps to 01 BB.
Verify: correct wire bytes 01 BB decode big-endian as 01 ⋅ 256 + BB = 256 + 187 = 443 . ✓ The naive BB 01 decodes to 0xBB01 = 47873 = 443 . ✓ See Network Protocols for htons/htonl.
Worked example C11 — Read one 4-byte int as two 2-byte halves
Forecast: on a little-endian machine, uint32_t x = 0xAABBCCDD is reinterpreted through a pointer as two uint16_t halves h[0], h[1]. What are they?
Lay bytes in memory (little-endian). Bytes b 0 = D D , b 1 = C C , b 2 = B B , b 3 = AA → 100:DD, 101:CC, 102:BB, 103:AA. Why this step? Type-punning reads whatever bytes are physically there, so we need the true layout first.
h[0] reads bytes at 100–101 as a 16-bit little-endian value: DD + CC ⋅ 256 = 0xCCDD . Why? Same LSB-first rule at half the width.
h[1] reads bytes at 102–103: BB + AA ⋅ 256 = 0xAABB .
Verify: 0xCCDD = 52445 and 0xAABB = 43707 ; and reassembling h [ 0 ] + h [ 1 ] ⋅ 2 16 = 52445 + 43707 ⋅ 65536 = 2864434397 = 0xAABBCCDD = original x . ✓ On a big-endian machine the same trick gives h [ 0 ] = 0xAABB , h [ 1 ] = 0xCCDD — swapped — which is exactly why type-punning code is endianness-dependent. See Pointers and Type Punning .
Worked example C12 — A struct with fields of different widths
Forecast: in struct { uint8_t a; uint16_t b; uint32_t c; } with a=0x11, b=0x2233, c=0x44556677, guess how many bytes each field swaps under endianness.
Assign offsets with alignment. Why this step? A uint16_t must sit at an even offset and a uint32_t at a multiple of 4, so the compiler inserts padding . Layout: offset 0 = a, offset 1 = pad , offsets 2–3 = b, offsets 4–7 = c. Total size 8.
Each field swaps independently , within its own bytes only. Why? Endianness acts on each multi-byte scalar separately; the a byte and the pad byte never move.
Little-endian: 0:11, 1:pad, 2:33, 3:22, 4:77, 5:66, 6:55, 7:44.
Big-endian: 0:11, 1:pad, 2:22, 3:33, 4:44, 5:55, 6:66, 7:77.
Field a (1 byte) never changes; b reverses its 2 bytes; c reverses its 4 bytes. Padding stays put in both.
Verify: reconstruct b from little-endian bytes at 2–3: 33 + 22 ⋅ 256 = 0x2233 = 8755 . Reconstruct c from little-endian bytes 4–7: 77 + 66 ⋅ 256 + 55 ⋅ 25 6 2 + 44 ⋅ 25 6 3 = 0x44556677 = 1146447479 . ✓ Figure s05 shows the byte grid with padding shaded and each field's arrows swapping separately.
Recall Did we fill every cell of the matrix?
C1 baseline ::: C1 example (0x0A0B0C0D)
C2 16-bit ::: C2 example (0xBEEF)
C3 64-bit ::: C3 example (0x11..88)
C4 zero degenerate ::: C4 example (0x00000000)
C5 partial symmetry ::: C5 example (0x12341234)
C6 leading zeros / narrow read ::: C6 example (0x00000005)
C7 negative / sign bit ::: C7 example (-2 = 0xFFFFFFFE)
C8 string not scalar ::: C8 example ("Helo")
C9 read back → value ::: C9 example (0x1234CDAB)
C10 network transmission ::: C10 example (port 443)
C11 sub-word type-pun ::: C11 example (0xAABBCCDD halves)
C12 mixed-type struct ::: C12 example (a/b/c with padding)
Mnemonic One line to carry it all
"Little end leads, big end begins." Little-endian: LSB at the low address (leads); big-endian: MSB at the beginning. Every example above is just that rule plus careful byte-extraction with b k = ⌊ V /25 6 k ⌋ mod 256 .
Endianness — parent topic — the core rule these examples exercise.
Data Representation — the V = ∑ b k 25 6 k decomposition every example rests on.
Memory Addressing — offsets and low/high addresses used throughout.
Network Protocols — C10's big-endian "network byte order" and htons.
Pointers and Type Punning — C11's sub-word reinterpretation and C12's struct layout.
Bitwise Operations — the shift/mask that implements byte extraction.
Instruction Set Architecture (ISA) — the CPU commits to one endianness.