If you are looking at an 8-bit microcontroller register reading 10110101 in binary, the direct decimal conversion is 181 (if interpreted as an unsigned integer) or -75 (if interpreted as a signed integer using two's complement). There is no single universal answer; the correct decimal value depends entirely on the bit-width, signedness, and memory endianness defined by your specific hardware datasheet.

The foundational formula for positional binary-to-decimal conversion is:

Decimal = (dn × 2n) + (dn-1 × 2n-1) + ... + (d0 × 20)

Substituting our 8-bit value (10110101):

(1×128) + (0×64) + (1×32) + (1×16) + (0×8) + (1×4) + (0×2) + (1×1) = 128 + 32 + 16 + 4 + 1 = 181.

The Core Formula and Neighboring Values

When debugging shift registers like the 74HC595 or reading GPIO port states on an Arduino, you rarely need to calculate just one number. You usually need to recognize a range of values. Below is a reference table of neighboring values within a ±20% range of our target 181, showing how the binary string shifts as the decimal value increments. Notice how the lower four bits cycle rapidly while the upper bits act as coarse multipliers.

Decimal (Unsigned) Binary (8-Bit) Hexadecimal Two's Complement (Signed)
145 10010001 0x91 -111
163 10100011 0xA3 -93
181 10110101 0xB5 -75
199 11000111 0xC7 -57
217 11011001 0xD9 -39

What Assumptions Fix Your Answer? (Bit-Width & Endianness)

In AC power calculations, voltage and phase angle fix your answer. In digital logic, bit-width, signedness, and endianness fix your answer. A raw binary string is meaningless without these three assumptions.

How the answer shifts for 8-bit vs 16-bit vs 32-bit:
If your compiler reads 10110101 as an 8-bit signed integer (int8_t), the leading 1 flags it as negative, yielding -75. If you cast that exact same 8-bit variable into a 16-bit signed integer (int16_t) without proper sign-extension, the compiler pads the left side with zeros: 00000000 10110101. Your value suddenly shifts from -75 to +181. Proper sign-extension requires padding with ones (11111111 10110101) to preserve the -75 value across wider bus architectures.

Endianness in 16-bit and 32-bit registers:
When reading multi-byte registers over I2C or SPI, byte order dictates the final decimal value. The ESP32 Technical Reference Manual explicitly defines its memory architecture as little-endian. Here is how the exact same two memory bytes yield vastly different decimal results depending on architecture:

Memory Layout (Byte 0, Byte 1) Architecture Interpretation Decimal Value Hex Equivalent Common Use Case
0xB5, 0x00 Unsigned Little-Endian 181 0x00B5 ESP32 local memory dump
0x00, 0xB5 Unsigned Big-Endian 181 0x00B5 Network packet header (TCP/IP)
0xB5, 0xFF Signed Little-Endian -75 0xFFB5 16-bit Audio PCM sample
0xFF, 0xB5 Signed Big-Endian -75 0xFFB5 Standard 16-bit integer (Motorola)

When Direct Binary-to-Decimal Conversion is Meaningless

Applying the standard positional formula will give you mathematically correct, but practically useless, garbage if the binary data is encoded using a non-standard scheme. You must recognize these three edge cases on the bench:

  • Binary Coded Decimal (BCD): Real-time clock modules like the DS3231 store time in BCD to simplify human-readable decoding. In BCD, each nibble (4 bits) represents a single base-10 digit. The binary string 0011 0101 in BCD means "35" (3 and 5). If you apply standard binary conversion, you get 53. Direct conversion is meaningless here; you must mask and shift the nibbles separately.
  • IEEE 754 Floating Point: If you are pulling a 32-bit float from a sensor via Modbus, the binary string includes a sign bit, an 8-bit exponent, and a 23-bit mantissa. As outlined in the NIST IEEE 754 standard documentation, treating this string as a standard integer will yield a massive, incorrect number. You must cast the memory pointer to a float in C/C++ or use a hex-to-float parser.
  • ASCII Encoded Text: If your UART sniffer captures 01000001, standard conversion yields 65. But in the context of a serial terminal, 65 is the ASCII decimal value for the capital letter "A". The "decimal" value is an intermediate abstraction; the actual payload is alphanumeric.

FAQ: Debugging Microcontroller Register Math

Why does my Arduino print a negative number when the binary string starts with 1?
Because the default int type on 8-bit AVRs (like the ATmega328P) is a 16-bit signed integer. If you bit-shift a 1 into the highest bit of a 16-bit signed variable, the compiler interprets it as a negative two's complement number. Force the variable type to uint16_t (unsigned) to read the true positive decimal value.

How do I quickly convert binary to decimal in my head without a calculator?
Memorize the "hex bridge." Split the 8-bit binary string into two 4-bit nibbles. Convert each nibble to its hexadecimal equivalent (e.g., 1011 = B = 11; 0101 = 5). Then calculate (11 × 16) + 5 = 181. It is significantly faster to multiply by 16 than to add 128 + 32 + 16 + 4 + 1 under pressure.

Is there a difference between converting a logic analyzer trace vs a datasheet register map?
Yes. A logic analyzer captures physical wire states (usually strictly unsigned, representing high/low voltage). A datasheet register map often defines specific bits as signed two's complement offsets (like a temperature sensor's fractional degree reading). Always check the datasheet's "Data Format" column before applying the conversion formula.