In a real circuit or microcontroller installation, misunderstanding this conversion changes a perfectly valid -10°C temperature sensor reading into a nonsensical +246°C, causing your HVAC control logic to fail, or causes a quadrature encoder to report a massive positive position jump when a motor reverses past zero. Modern microcontrollers like the AVR in an Arduino Uno or the Xtensa/RISC-V cores in an ESP32 do not natively understand a "minus" symbol; they rely entirely on a system called two's complement to handle negative math at the silicon level.
The Core Mechanism: Two's Complement vs. Sign-Magnitude
When we need to represent negative numbers in binary, the most intuitive approach for humans is sign-magnitude, where the leftmost bit simply acts as a plus or minus sign (e.g., 10000010 means -2). However, hardware arithmetic logic units (ALUs) hate sign-magnitude because it requires separate, complex circuitry to handle addition and subtraction depending on the sign bits.
Instead, embedded systems use two's complement. In this system, the most significant bit (MSB) still acts as the sign indicator (0 for positive, 1 for negative), but the remaining bits are weighted such that standard binary addition hardware works flawlessly across the zero boundary without extra logic gates. To find the decimal value of a negative two's complement binary number, you invert all the bits (change 1s to 0s and 0s to 1s) and add 1 to the result.
Below is a data-dense reference table for an 8-bit signed integer (int8_t in C++). Notice how the binary sequence flows continuously from the maximum positive value directly into the maximum negative value.
| Decimal Value | 8-Bit Signed Binary (Two's Complement) | Hexadecimal | Hardware State / Notes |
|---|---|---|---|
| +127 | 0111 1111 |
0x7F |
Maximum positive 8-bit value |
| +2 | 0000 0010 |
0x02 |
Standard positive integer |
| +1 | 0000 0001 |
0x01 |
Standard positive integer |
| 0 | 0000 0000 |
0x00 |
Zero (only one representation) |
| -1 | 1111 1111 |
0xFF |
All bits high; adding 1 causes overflow to 0 |
| -2 | 1111 1110 |
0xFE |
Standard negative integer |
| -10 | 1111 0110 |
0xF6 |
Common sensor offset value |
| -22 | 1110 1010 |
0xEA |
Used in worked example below |
| -127 | 1000 0001 |
0x81 |
Near minimum negative limit |
| -128 | 1000 0000 |
0x80 |
Minimum negative value (no positive +128 equivalent) |
Reference: For a deeper dive into ALU hardware implementation of these binary states, see the All About Circuits textbook chapter on signed binary numbers.
Worked Numeric Example: Converting an 8-Bit Sensor Reading
Let's say you are reading an I2C temperature sensor that returns an 8-bit two's complement value. Your microcontroller reads the raw byte over the I2C bus and stores it as 11101010 (or 0xEA in hex). If you treat this as an unsigned integer, your code will read it as 234. But the sensor is sitting in a freezer, so 234°C is physically impossible. Here is how you manually convert 11101010 to its true signed decimal value.
- Identify the Sign Bit: Look at the most significant bit (the far left). It is a
1. This tells us the number is negative. - Invert the Bits: Flip every 1 to a 0, and every 0 to a 1.
Original:1110 1010
Inverted:0001 0101 - Add One: Add 1 to the inverted binary number.
0001 0101+0000 0001=0001 0110 - Convert to Decimal: Calculate the base-10 value of this new positive binary number.
0001 0110= 16 + 4 + 2 = 22 - Apply the Sign: Because the original sign bit was 1, apply the negative sign.
Final Decimal Value: -22
uint8_t variable named raw_byte, simply cast it to a signed 8-bit integer: int8_t temp = (int8_t)raw_byte;. The compiler maps the 0xEA memory directly to -22 in a single clock cycle.
Where You Meet Signed Binary in Practice
Understanding signed binary to decimal conversion is not just an academic exercise; it dictates how you wire, configure, and write firmware for several common embedded subsystems.
1. Inertial Measurement Units (IMUs) and Accelerometers
When you wire up an MPU6050 accelerometer to an ESP32 via I2C, the chip outputs 16-bit signed integers for the X, Y, and Z axes. Because the I2C bus transfers data one byte at a time, you receive a High Byte and a Low Byte. If you simply concatenate them into an unsigned 16-bit integer (uint16_t), tilting the sensor left will yield a massive positive number near 65,000 instead of a negative G-force. You must combine the bytes and cast the result to a int16_t to allow the two's complement format to resolve the negative vector correctly.
2. Digital Audio and I2S Microphones
If you are building a voice-activated relay using an INMP441 I2S MEMS microphone, the audio data is streamed as 24-bit signed PCM (Pulse Code Modulation) data. Sound waves are alternating pressure gradients; the silence baseline is exactly zero. Positive binary values represent the compression phase of the sound wave, and negative two's complement values represent the rarefaction phase. If your DSP code treats the I2S buffer as unsigned, the audio waveform will be severely DC-offset, resulting in blown speakers or failed FFT frequency analysis. The Espressif ESP-IDF I2S driver documentation explicitly configures the DMA buffers to handle these signed bit-shifts automatically, provided you select the correct I2S_BITS_PER_SAMPLE_16BIT or 24-bit enum.
3. Quadrature Encoders and Motor Control
When tracking the position of a stepper motor or DC motor with a quadrature encoder, the counter must increment when spinning forward and decrement when spinning in reverse. The hardware counter registers in microcontrollers (like the PCNT peripheral on the ESP32) utilize signed integers so that reversing past the physical "home" zero switch seamlessly rolls the decimal position into negative territory without requiring complex software subtraction logic.
Common Confusions and Debugging Mistakes
When debugging sensor anomalies on the workbench, hobbyists frequently misdiagnose signed binary issues. Here is a breakdown of what people commonly confuse with standard two's complement signed binary.
Is signed binary the same as Binary Coded Decimal (BCD)?
No. This is a very common confusion when working with Real Time Clocks (RTCs) like the DS3231. BCD does not use the whole byte for a single mathematical value. Instead, it splits the 8-bit byte into two 4-bit nibbles, each representing a single base-10 digit (0-9). For example, the decimal number 45 is 0100 0101 in BCD, but 0010 1101 in standard binary. If you apply two's complement conversion math to a BCD register, your time and date calculations will be completely wrong. Always check the sensor datasheet to see if the output is Two's Complement or BCD.
Why does my 16-bit ADC read 65535 when the voltage goes slightly negative?
This happens when you read a signed sensor output into an unsigned variable type (like uint16_t instead of int16_t). In a 16-bit unsigned system, the decimal value 65535 is represented by 1111 1111 1111 1111. In a 16-bit signed two's complement system, that exact same binary sequence represents -1. If your ADC is measuring a -1mV offset and your code stores it in an unsigned integer, the compiler reads the all-high bits as the maximum possible positive number. The fix is always to ensure your variable declaration matches the signed/unsigned nature of the hardware register.
What is the difference between Two's Complement and Sign-Magnitude?
While both represent negative numbers, sign-magnitude uses the MSB strictly as a flag, leaving the remaining bits as a standard positive number. This results in two different binary representations for zero (00000000 for +0, and 10000000 for -0). Two's complement only has one zero. Furthermore, sign-magnitude is largely obsolete in modern integer math, though it still appears in the exponent/mantissa structure of IEEE 754 floating-point numbers. If you are reading raw integer registers from an InvenSense MPU-6000 series IMU, it is strictly two's complement; attempting to parse it as sign-magnitude will yield erratic telemetry data.
if (val > MAX) val = MAX;) in your control loop before passing the signed decimal value to your PWM generation function to prevent mechanical damage or injury.






