SNIPPET 7

Sign Extension

Convert an N-bit signed value packed inside a larger unsigned variable into a true, native signed integer.

Silicon Logic

In hardware, a negative number is identified by its Most Significant Bit (MSB) being set to 1 (Two's Complement).

However, if a peripheral outputs a 12-bit signed number, the MSB is at bit index 11. The CPU stores this inside a standard 16-bit or 32-bit register, where bit 11 means nothing to native math. It just looks like a large positive number.

The Bitwise Trick: We must propagate that 12th bit all the way out to the 32nd bit.
By shifting the MSB to the extreme absolute-left, then doing a Signed Right Shift, C natively triggers an ASR (Arithmetic Shift Right) CPU Instruction which mathematically copies the sign bit across the empty space.

adc_driver.c
#include <stdint.h>
// Extends a 12-bit hardware packet into a 32-bit CPU integer
int32_t sign_extend_12bit(uint16_t x) {
// 1. Left shift 20 bits (32 - 12) to force the 12th bit to MSB
int32_t shifted = (int32_t)x << 20;
// 2. Arithmetic Right Shift (ASR) propagates the sign bit backwards
int32_t result = shifted >> 20;
return result;
}
int main() {
// Sensor outputs 0x0FFF (which is mathematically -1 in 12-bit scope)
uint16_t raw_adc = 0x0FFF;
// CPU natively sees 0x0FFF as a massive positive number (4095)
int32_t true_voltage = sign_extend_12bit(raw_adc);
return 0;
}