Converting the 8-bit binary byte 10110101 to decimal yields 181 if treated as an unsigned integer, or -75 if treated as a signed two's complement integer. The foundational formula for positional weight is D = Σ(bn × 2n). For our target byte 10110101, the unsigned substitution is: (1 × 128) + (0 × 64) + (1 × 32) + (1 × 16) + (0 × 8) + (1 × 4) + (0 × 2) + (1 × 1) = 181. If you are reading a microcontroller register or parsing a sensor payload, the raw bits on the wire do not change, but your assumed data type dictates the final decimal output.

The Core Formula and Neighboring Values (±20% Range)

In digital logic, every bit position represents a power of 2, starting from 20 on the far right (the Least Significant Bit, or LSB) and increasing to the left. To convert any binary string to a base-10 decimal, you multiply each bit by its positional weight and sum the results. This is identical to how we read decimal numbers (hundreds, tens, ones), just with a base-2 multiplier instead of base-10.

When debugging sensor data or memory dumps, you rarely look at a single isolated byte. Below is a reference table covering the ±20% range around our target value of 181 (spanning decimal 145 to 217). This helps you quickly verify if a slightly shifted binary read (due to noise or a drifting ADC) is landing in the expected neighborhood.

Binary to Decimal Neighboring Values (±20% of 181)
Binary (8-bit) Hex Equivalent Unsigned Decimal (uint8_t) Signed Decimal (int8_t)
10010001 0x91 145 -111
10100000 0xA0 160 -96
10110101 0xB5 181 (Target) -75 (Target)
11001000 0xC8 200 -56
11011001 0xD9 217 -39

What Assumption Fixes the Answer? (Bit-Width and Signedness)

In AC power theory, your final wattage calculation shifts drastically depending on whether you assume 120V vs 230V vs 3-phase. In embedded systems, the exact same principle applies to converting from binary to decimal: the answer shifts entirely based on whether you assume an 8-bit vs 16-bit vs 32-bit register, and whether the Most Significant Bit (MSB) is treated as a sign indicator.

Bench Rule of Thumb: The hardware doesn't know what a "negative number" is. It only knows high and low voltage states. Signedness is purely a software illusion created by the Two's Complement standard. Always check the sensor datasheet to see if it outputs unsigned magnitude or two's complement.

Here is how the decimal answer for the exact same bit pattern (...10110101) shifts across different architectural assumptions:

  • 8-Bit Unsigned (uint8_t): The MSB (bit 7) is just another value bit (128). The answer is 181. The valid range is 0 to 255.
  • 8-Bit Signed (int8_t): The MSB is the sign bit. Because it is a '1', the number is negative. We invert the bits and add 1 to find the magnitude. The answer is -75. The valid range is -128 to 127.
  • 16-Bit Unsigned (uint16_t): If the byte is padded with zeros on the left (00000000 10110101), the answer remains 181.
  • 16-Bit Signed (int16_t): If the byte is sign-extended with ones on the left (11111111 10110101), the answer remains -75. However, if you mistakenly pad an 8-bit negative number with zeros into a 16-bit signed integer, the MSB becomes 0, and the system reads it as a positive 181, introducing a massive calculation error in your control loop.

When the Conversion is Meaningless (Encoding Traps)

Just as calculating real power (Watts) is meaningless if you don't know the Power Factor (PF) in an inductive AC circuit, converting raw binary to decimal is meaningless if you misidentify the underlying encoding scheme. If you apply the standard base-2 formula to the wrong data format, you will get a mathematically correct but practically useless number.

Trap 1: Binary Coded Decimal (BCD)

Many real-time clocks (like the DS3231) and legacy digital multimeters output data in BCD, where every 4-bit nibble represents a single base-10 digit (0-9). If you receive the byte 1011 0101 and try to read it as pure binary, you get 181. But in BCD, the upper nibble 1011 equals 11. Since standard 8421 BCD only supports 0-9 per nibble, 1011 is an invalid BCD state. The conversion to 181 is meaningless; the actual intended decimal was likely corrupted in transit, or you are reading a status flag instead of a time register. For a deep dive on hardware encoding, refer to the All About Circuits digital logic chapter on number formats.

Trap 2: IEEE 754 Floating Point

If you read a 32-bit memory address holding a floating-point temperature reading (e.g., 23.5°C) and apply an integer binary-to-decimal conversion, you will get a massive, meaningless integer like 1109917696. The bits are structured into a sign bit, an 8-bit exponent, and a 23-bit mantissa. You must cast the memory pointer to a float in C/C++ rather than parsing the raw binary manually.

Decision Tree: Pick the Right Decoder for Your Register

Use this decision path when writing firmware to parse incoming I2C, SPI, or UART payloads. Follow the logic down to terminate at the exact C/C++ data type or decoding function you need to implement.

Condition / Observation Next Step Final Implementation Pick
Does the datasheet specify the value is a raw magnitude (e.g., ADC count, PWM duty)? Check bit-width. Is it ≤ 255? Cast to uint8_t (Unsigned 8-bit)
Does the datasheet specify the value can cross zero (e.g., accelerometer X/Y/Z axis, signed temperature)? Check bit-width. Is it 8-bit? Cast to int8_t (Signed Two's Complement)
Is the payload from a Real Time Clock (RTC) or a legacy digital panel meter? Verify if it uses 8421 BCD encoding. Use bitwise BCD decode: ((val >> 4) * 10) + (val & 0x0F)
Are you reading a 16-bit value over I2C, but the bytes seem swapped? Check Endianness (Big vs Little). Use Wire.read() << 8 | Wire.read() for Big-Endian sensor registers.

FAQ: Embedded Binary Conversion Edge Cases

Why does my ESP32 print a negative number when the sensor value should be positive?

You are likely reading a 16-bit sensor register into an 8-bit signed variable, or you are failing to mask the upper bits. If a 12-bit ADC returns 1000 0000 0000 (2048) and you shove it into an int16_t without padding correctly, the sign bit might get flipped. Always use uint16_t for raw ADC counts before applying your voltage scaling formula. See the Arduino Bit Math documentation for proper masking techniques.

How do I handle endianness when converting multi-byte binary to decimal?

Endianness dictates byte order, not bit order. If a sensor sends the 16-bit value 0x01B5 (437 in decimal) over I2C, a Big-Endian device sends 0x01 then 0xB5. A Little-Endian device (like an x86 PC or some ARM Cortex setups) sends 0xB5 then 0x01. If your decimal output looks wildly wrong but contains the right hex characters, swap your byte shift order: (LSB << 8) | MSB.

Is there a hardware shortcut for binary-to-BCD conversion?

Yes. If you are driving 7-segment displays directly from an FPGA or CPLD, you don't need to write software division loops. You can implement the "Double Dabble" (Shift-and-Add-3) algorithm in hardware logic gates, which shifts the binary bits into BCD nibbles in exactly n clock cycles, where n is the bit-width of your binary input.