· SOFTWARE

Endianness and IEEE 754: the bug that sends you back to the datasheet

One of the most frustrating bugs we hit when integrating third-party instrumentation isn’t in an algorithm: it’s in four bytes read in the wrong order. The instrument claims to expose a physical quantity as a 32-bit float in a register; we read it and get 1.7e+38, or -0.0000000000000000003, or a clean NaN. The true value was 23.7. Neither side is wrong about the protocol: we just misunderstood each other on how those bytes should be reassembled.

The case

A typical chain: a meter exposes a reading over Modbus, two consecutive 16-bit registers that together form a 32-bit float. Our side reads the registers, concatenates them, interprets them as float, and prints a number with no physical meaning. The first reaction, and the wrong one, is to doubt your own parsing algorithm. The right reaction is to drop down to the single-byte level and ask two distinct questions: in what order do the bytes arrive, and how do those bytes encode a number. These are two independent problems, and when the values read are implausible, rule out byte order before questioning the encoding.

Endianness: the same number, bytes in a different order

A 32-bit integer or float is four bytes. Endianness is the convention for which byte comes first in memory or on the wire. Big-endian puts the most significant byte (MSB) first, in the order we’d write the number by hand; little-endian puts the least significant (LSB) first. The four bytes 41 BD 70 A4 interpreted big-endian are 23.68; the same bytes read little-endian, i.e. A4 70 BD 41, are a completely different and meaningless float.

Modbus complicates things because it works in big-endian 16-bit registers, but doesn’t specify the order between the two registers of a 32-bit float. So in practice up to four variants arise — ABCD, CDAB, BADC, DCBA — depending on whether the vendor swaps bytes, words, both, or neither (the notorious word swap). The datasheet, if well written, tells you which; if badly written, you find out by hand. That’s why, faced with absurd numbers, the first move is to systematically try the four byte orders: if one of the permutations returns the expected value, the problem was endianness and not decoding.

IEEE 754: how bytes become a number

Once the bytes are in the right order, the second problem remains: what they mean. A 32-bit float follows the IEEE 754 single-precision standard, which splits the 32 bits into three fields: 1 sign bit, 8 exponent bits (with a bias of 127), 23 mantissa bits (with an implicit leading 1). The value is roughly (-1)^sign · 1.mantissa · 2^(exponent−127). Understanding this decomposition is what lets you tell an endianness error from a legitimately small or large value: if the exponent field is all ones you’re looking at an infinity or a NaN, and almost always that means the bytes are in the wrong order, not that the instrument is broken.

For integers the twin trap is the sign. Negative values are encoded in two’s complement: invert all the bits and add 1. Reading a 16-bit register as unsigned when the instrument intends it signed makes a -3 show up as 65533 — again an “absurd” number that is really just interpreted with the wrong convention. And as with floats, on a multi-register value the byte order must be resolved before applying two’s complement.

The method, not the anecdote

The lesson we carry from this isn’t “watch out for Modbus”. It’s a method: when a numeric value read from a protocol or a register is absurd, drop down to the raw byte and separate the two levels. First, the byte order — big or little, with a possible word swap. Second, the encoding — IEEE 754 for floats, two’s complement for signed integers. Resolved in the right order, the number comes back; and almost always the answer was already in the datasheet, in a line we hadn’t read on the first pass.

To inspect any four bytes by hand across the different orders and encodings we put a Data Format Inspector online; the detail on endianness, IEEE 754 and two’s complement is in the dedicated wiki.

Integrating instrumentation over Modbus, serial, or a custom binary protocol and the numbers don’t add up? Let’s talk.

← Back to blog

A technical project?

Hardware, firmware, software, acoustics: if you have a related use case, let’s talk.