Endianness matters in the following situations:
- You're directly examining/manipulating bytes in a multi-byte type
- You're serializing binary data, or transferring binary data between different architectures
Directly examining/manipulating bytes in a multi-byte type
For example, suppose you want to split out and display the binary representation of a 32-bit IEEE float. The following shows the layout of a float and the addresses of the corresponding bytes in both big- and little-endian architectures:
A A+1 A+2 A+3 Big endian
-------- -------- -------- -------- s = sign bit
seeeeeee efffffff ffffffff ffffffff e = exponent bit
-------- -------- -------- -------- f = fraction bit
A+3 A+2 A+1 A Little Endian
-------- -------- -------- --------
A+1 A A+3 A+2 "Middle" Endian (VAX)
The sign bit is in the most significant byte (MSB) of a float. On a big-endian system, the MSB is in byte A
; on a little-endian system, it's in byte A+3. On some oddballs like the old VAX F float, it's stuck in the middle at byte A+1
.
So if you want to mask out the sign bit, you could do something like the following:
float val = some_value();
unsigned char *p = (unsigned char *) &val; // treat val as an array of unsigned char
// Assume big-endian to begin with
int idx = 0;
if ( little_endian() )
idx = 3;
int sign = (p[idx] & 0x80) >> 7
Serializing or transferring binary data
For another example, you want to save binary (not text) data such that it can be read by either big- or little-endian systems, or you're transferring binary data from one system to a another. The convention for Internet transfers is big-endian (MSB first), so prior to sending a message over the 'net, you'd use calls like htonl
(host-to-network long) and htons
(host-to-network short) to perform any necessary byte swaps prior to sending the data:
uint32_t host_value = some_value();
uint32_t network_value = htonl( host_value );
send( sock, &network_value, sizeof network_value, 0 );
On a little-endian system like x86, htonl
will reorder the bytes of host_value
from 0,1,2,3 to 3,2,1,0 and save the result to network_value
. On a big-endian system, htonl
is basically a no-op. The inverse operations are ntohl
and ntohs
.
If you're not doing anything like the above, then you generally don't have to worry about endianness at all.