The binary number table maps base-2 logic states to human-readable decimals and hexadecimal values. For an 8-bit microcontroller register (like the ATmega328P PORTB on an Arduino Uno), the absolute range spans from 00000000 (0) to 11111111 (255). If you are writing firmware, debugging I2C payloads, or configuring GPIO pin masks, you need immediate access to these boundary values without running a calculator script. Below is the master reference chart for 8-bit and 16-bit boundaries, followed by the bitwise rules that govern how these values behave in physical hardware.
How to Read This Binary Number Table
Unlike NEC wire sizing charts where the temperature rating (60°C vs 75°C column) dictates the safe ampacity, this binary reference relies on bit-width and signedness ratings to dictate the safe numeric range. The table below contains four primary columns:
- Decimal (Unsigned): The raw base-10 value from 0 to 255 (for 8-bit) or 65535 (for 16-bit). Use this column when configuring ESP32-WROOM-32 GPIO port expanders or setting Arduino PWM duty cycles.
- Decimal (Signed 8-bit/16-bit): Uses two's complement arithmetic. Use this column when parsing sensor data (like the TMP102 I2C temperature sensor) or handling motor encoder ticks that can go negative.
- Hexadecimal: The base-16 shorthand. Essential for writing C++ bitwise masks (e.g.,
0xFF) and reading logic analyzer outputs. - Binary: The literal 1s and 0s representing the physical HIGH/LOW states of the silicon register.
11111111 as 255 instead of -1 is the root cause of 90% of runaway motor controller bugs.
The Master Binary, Hex, and Decimal Reference Chart
Source Standards: Logic states and binary prefixes per ISO/IEC 80000-13; floating-point and signed arithmetic boundaries per ANSI/IEEE Std 754.
This table includes the full 4-bit sequence (0-15) for quick nibble lookups, followed by the critical 8-bit and 16-bit boundary rows that trigger overflow and sign-flip errors in C/C++ environments.
| Decimal (Unsigned) | Decimal (Signed) | Hex | Binary (8-bit / 16-bit) | Notes / Quick-Jump |
|---|---|---|---|---|
| 0 | 0 | 0x00 | 0000 0000 | Ground / Logic LOW |
| 1 | 1 | 0x01 | 0000 0001 | LSB (Least Significant Bit) |
| 2 | 2 | 0x02 | 0000 0010 | Bit 1 set |
| 3 | 3 | 0x03 | 0000 0011 | Bits 0 & 1 set |
| 4 | 4 | 0x04 | 0000 0100 | Bit 2 set |
| 5 | 5 | 0x05 | 0000 0101 | - |
| 6 | 6 | 0x06 | 0000 0110 | - |
| 7 | 7 | 0x07 | 0000 0111 | Lower nibble max (partial) |
| 8 | 8 | 0x08 | 0000 1000 | Bit 3 set |
| 9 | 9 | 0x09 | 0000 1001 | - |
| 10 | 10 | 0x0A | 0000 1010 | - |
| 11 | 11 | 0x0B | 0000 1011 | - |
| 12 | 12 | 0x0C | 0000 1100 | - |
| 13 | 13 | 0x0D | 0000 1101 | - |
| 14 | 14 | 0x0E | 0000 1110 | - |
| 15 | 15 | 0x0F | 0000 1111 | Lower nibble max (4-bit) |
| 127 | 127 | 0x7F | 0111 1111 | 8-bit Signed MAX |
| 128 | -128 | 0x80 | 1000 0000 | 8-bit Signed MIN / MSB set |
| 255 | -1 | 0xFF | 1111 1111 | 8-bit Unsigned MAX / All HIGH |
| 256 | 256 | 0x0100 | 0000 0001 0000 0000 | 8-bit Overflow / 16-bit start |
| 32767 | 32767 | 0x7FFF | 0111 1111 1111 1111 | 16-bit Signed MAX (Arduino int) |
| 32768 | -32768 | 0x8000 | 1000 0000 0000 0000 | 16-bit Signed MIN |
| 65535 | -1 | 0xFFFF | 1111 1111 1111 1111 | 16-bit Unsigned MAX |
How Bit-Shifting and Overflow 'Derate' Your Base Values
In electrical wiring, ambient temperature derating modifies a wire's base ampacity when bundling conductors in a conduit. In digital logic, bit-shifting and register overflow modify your base binary value when scaling data or passing variables between functions.
When you left-shift (<<) a binary number, you multiply it by 2. But if you push a 1 into the Most Significant Bit (MSB) of a signed variable, you cross the sign boundary. For example, take the unsigned value 96 (0110 0000). If you left-shift it by 1, the binary becomes 1100 0000.
- In an Unsigned 8-bit register: The value scales cleanly to 192.
- In a Signed 8-bit register: The MSB is now 1, flipping the sign. The value 'derates' instantly to -64.
This is the digital equivalent of a thermal derating curve. If your code does not explicitly cast variables to uint8_t or uint16_t (unsigned), the compiler's default signed behavior will silently corrupt your math the moment you cross the 127 (8-bit) or 32767 (16-bit) threshold. Always use explicit unsigned types when manipulating GPIO masks or raw sensor bytes.
What This Binary Table Cannot Tell You
While this table gives you the exact mathematical mapping of bits to decimals, it lacks the physical and architectural context of your specific microcontroller. Keep these three blind spots in mind:
- Endianness: The table shows 16-bit values as a single block (e.g.,
0x0100for 256). However, the ESP32 (Xtensa LX6 architecture) is little-endian, meaning it stores the least significant byte (0x00) at the lower memory address. If you are casting a byte array to a 16-bit integer over UART, you must account for byte order, or your values will invert. - Physical Pin Mapping: A binary 1 in Bit 0 of the ATmega328P
PORTDregister does not map to Arduino Digital Pin 0. Due to internal UART routing,PORTDBit 0 is actually RX (Digital Pin 0), but Bit 1 is TX (Digital Pin 1), and the mapping scatters across the physical DIP package. Always check the silicon datasheet's pinout, not just the binary table. - Floating-Point Representation: This table does not apply to 32-bit floats. Under the IEEE 754 standard, a 32-bit float dedicates 1 bit to the sign, 8 bits to the exponent, and 23 bits to the mantissa. You cannot use standard binary-to-decimal conversion on a float register; you must use a hex-to-float converter tool.
Binary Number Table FAQ
How do I use a binary number table for 16-bit Arduino analogRead() values?
Standard Arduinos (Uno/Nano) use a 10-bit ADC, returning values from 0 to 1023. However, if you are using an ESP32 or an external 16-bit ADC like the ADS1115 over I2C, your range expands to 65535 (unsigned) or 32767 (signed). Use the jump-32767 and jump-65535 rows above to identify your maximum ceiling. When mapping this to a 5V reference, each binary step represents approximately 0.076mV (5.0V / 65535).
Why does my binary number table show negative decimals for high 8-bit values?
This is due to two's complement arithmetic, the standard method silicon uses to represent negative numbers without requiring a dedicated 'minus sign' bit. In an 8-bit signed integer, the MSB (Bit 7) acts as a negative weight (-128). Therefore, 1111 1111 is calculated as -128 + 64 + 32 + 16 + 8 + 4 + 2 + 1, which equals -1. If you want 1111 1111 to equal 255, you must declare your variable as an unsigned char or uint8_t in your C++ code.
How do I convert a binary number table value to an ESP32 PWM duty cycle?
The ESP32's LEDC peripheral does not use a standard 8-bit (0-255) PWM scale like the Arduino analogWrite() function. By default, the ESP32 uses a 13-bit or 8-bit resolution depending on your ledcSetup() configuration. If you set the resolution to 8 bits, the jump-255 row (100% duty cycle) applies directly. If you use the default 13-bit resolution, your maximum binary value is 8191. Always verify your ledc_timer_bit_t resolution setting before passing binary table values to the ledcWrite() function, or your motors and LEDs will behave erratically.






