Hexadecimal addition is the base-16 arithmetic process of summing digits (0-9 and A-F) and carrying over to the next column only when a sum reaches 16, rather than 10. While it doesn't change a single physical wire in a circuit, mastering this math dictates whether your microcontroller writes data to the correct flash memory sector, accurately calculates an I2C register pointer, or accidentally overwrites its own bootloader. Beginners commonly confuse hex addition with standard decimal addition—forgetting to carry at 16—or treat letters A-F as algebraic variables rather than fixed numeric values representing 10 through 15.

The Mechanics of Base-16 Arithmetic

To perform the addition of hexadecimal values on the bench, you must internalize that the column "rolls over" at 16. The digits are 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, A(10), B(11), C(12), D(13), E(14), F(15). When a column sum exceeds 15, you subtract 16, write down the remainder, and carry a 1 to the next leftward column.

Let's walk through a worked numeric example adding two memory offsets: 0x3B7 + 0x1C8.

  1. Rightmost column (1s place): Add 7 + 8. The sum is 15. In hex, 15 is represented by F. Because 15 is less than 16, there is no carry. Write down F.
  2. Middle column (16s place): Add B (11) + C (12). The decimal sum is 23. Since 23 is greater than 15, we subtract 16 (23 - 16 = 7). Write down 7 and carry a 1 to the next column.
  3. Leftmost column (256s place): Add 3 + 1 + 1 (the carry from the previous step). The sum is 5. Write down 5.
Final Result: 0x57F. If you were allocating a buffer starting at 0x3B7 and reading 0x1C8 bytes, your final memory pointer would rest exactly at 0x57F.

Where You Meet Hex Addition in Practice

You rarely add hex by hand when writing high-level Python or JavaScript, but in embedded C/C++ and hardware configuration, it is a daily requirement. Here is where inaccurate hex math causes physical or firmware failures:

  • Microcontroller Flash Partitions: Defining custom memory layouts for ESP32 or STM32 chips requires calculating exact start and end addresses for Over-The-Air (OTA) slots, file systems, and non-volatile storage (NVS).
  • I2C EEPROM Page Boundaries: Chips like the 24LC256 (32KB EEPROM) write data in 64-byte pages (0x40 in hex). If you start a write at address 0x0030 and write 32 bytes (0x20), the addition of hexadecimal values (0x0030 + 0x0020 = 0x0050) reveals that you crossed the 0x003F page boundary. The hardware will silently wrap the excess bytes back to 0x0000, corrupting your data.
  • Sensor Register Pointers: When reading multi-byte data from an IMU like the MPU6050, you often add an offset to the base register address to read the Y and Z axes sequentially.

Real-World Scenario Walkthrough: The ESP32 Partition Overlap

Theory is clean; firmware deployment is messy. Here is a real-world scenario where a miscalculation in hex addition bricked a fleet of prototype IoT sensors.

The Setup: A developer was building a custom OTA firmware for an ESP32-WROOM-32 module using the Arduino framework. To accommodate a large web server payload, they needed a custom partitions.csv file. The goal was to place the app0 partition, followed immediately by a spiffs (SPI Flash File System) partition for storing HTML assets.

The Numbers: The app0 partition was configured to start at offset 0x10000 with a massive size of 0x140000 (1.25 MB). The developer needed to calculate the exact start address for the spiffs partition, which must begin exactly where app0 ends.

The Outcome: The required math was 0x10000 + 0x140000. The developer, relying on mental math and pattern-matching the zeros, dropped a zero and set the spiffs offset to 0x140000 in the CSV file. The code compiled and flashed successfully.

What Went Wrong: Upon first boot, the ESP32 initialized the SPIFFS and formatted the drive. Because the offset was miscalculated, the format routine overwrote the last 64KB (0x10000 bytes) of the compiled application binary. The microcontroller immediately threw a Guru Meditation Error: Core 1 panic'ed (IllegalInstruction) and entered an infinite bootloop. The correct start address was 0x150000. According to the Espressif Partition Table documentation, overlapping partitions will always result in catastrophic memory corruption during runtime initialization.

Common Pitfalls and Troubleshooting Hex Math

Q: Why does my C++ compiler throw an error or allocate the wrong memory when I type 10000?
A: You forgot the 0x prefix. In C and C++, a number like 10000 is treated as a base-10 decimal (ten thousand). To force the compiler to interpret it as a hex value (65,536 in decimal), you must write 0x10000. The C++ integer constant reference strictly defines this prefix behavior.

Q: I added 0x8 + 0x9 and got 0x11. Is that right?
A: No. You carried at 10 instead of 16. In decimal, 8 + 9 = 17. In hex, 17 is represented as 0x11 (one 16, plus one 1). However, if you were adding 0x8 + 0xA (8 + 10), the decimal sum is 18. Subtract 16, and the hex result is 0x12.

Q: Does endianness affect hex addition?
A: Endianness (byte-swapping) does not change the mathematical rules of addition, but it drastically changes how you write the result to a network buffer or I2C bus. If you calculate a 16-bit address as 0x1A2B, a little-endian system (like most ARM Cortex-M chips) expects you to transmit the bytes in the order 0x2B then 0x1A. The math remains the same; the byte transmission order flips.

Quick Reference: Hex Addition Carry Rules

Keep this table on your bench when manually calculating memory offsets or verifying a logic analyzer's decoded output.

Decimal Sum Hex Representation Carry to Next Column? Common Bench Context
10 A No Reading a 10-byte sensor payload
15 F No Max value of a single nibble (4 bits)
16 10 Yes (Carry 1) Rolling over a 4-bit boundary
255 FF No Max value of an 8-bit register (1 byte)
256 100 Yes (Carry 1) Rolling over an 8-bit boundary into the 3rd byte

Mastering the addition of hexadecimal isn't about memorizing a new times table; it is about retraining your brain to recognize the 16-step boundary. Whether you are calculating the wrap-around point on an I2C EEPROM or sizing an ESP32 flash partition, treating A-F as hard numbers rather than abstract letters will save you hours of debugging bootloops and silent data corruption.