Binary Values
Part of Boolean Logic and Gates
Binary values are the representation of information as sequences of 0s and 1s — covering how integers, negative numbers, fractions, characters, and arbitrary data are encoded in the two-symbol system of digital hardware.
Why This Matters
A computer’s memory contains only binary values — patterns of 0s and 1s. Everything else — integers, text, images, audio, programs — is an interpretation of those patterns. Understanding binary value representations means understanding what the hardware actually stores and how software gives meaning to raw bit patterns.
This is not just theoretical. When debugging low-level code or hardware, you will inspect memory contents as hex dumps. Being able to look at “0xFF 0x80 0x41 0x00” and recognize “255, -128, character ‘A’, null terminator” is a practical skill. Misinterpreting a value’s encoding is a common source of bugs in systems programming.
Different domains use different encodings for good historical and technical reasons. Knowing all of them, and knowing which applies in a given context, is essential for working at the system level.
Unsigned Integers
The simplest interpretation: the binary pattern represents a non-negative integer by straightforward positional value.
N-bit unsigned integer range: 0 to 2^N − 1.
- 4 bits: 0–15
- 8 bits: 0–255 (byte)
- 16 bits: 0–65,535 (word)
- 32 bits: 0–4,294,967,295 (~4.3 billion)
No sign information. If the result of an operation exceeds 2^N − 1, the carry flag signals overflow and the stored result wraps (modular arithmetic).
Unsigned integers are appropriate for: counts, addresses, loop indices, pixel values (0–255 for color channels), bitmasks, character codes.
Two’s Complement Signed Integers
The standard representation for signed integers in all modern computer hardware. The key insight: interpret the most significant bit (MSB) as having a negative place value.
For an N-bit two’s complement value: Value = −(MSB × 2^(N−1)) + sum of remaining bit positional values
8-bit examples:
- 0b01111111 = −0 + 127 = +127 (maximum positive)
- 0b00000001 = −0 + 1 = +1
- 0b00000000 = 0
- 0b11111111 = −128 + 127 = −1
- 0b10000001 = −128 + 1 = −127
- 0b10000000 = −128 + 0 = −128 (minimum, most negative)
N-bit two’s complement range: −2^(N−1) to +2^(N−1) − 1.
- 8 bits: −128 to +127
- 16 bits: −32,768 to +32,767
- 32 bits: −2,147,483,648 to +2,147,483,647
Key property: addition and subtraction work identically for both signed and unsigned values using the same circuit. The hardware does not “know” whether the values are signed; the interpretation is provided by the programmer.
Test for negative: check the MSB. If bit 7 of an 8-bit value is 1, the value is negative (in two’s complement).
Sign-Magnitude and One’s Complement (Historical)
Before two’s complement was standardized, other signed representations existed:
Sign-magnitude: MSB is the sign bit (0=positive, 1=negative); remaining bits represent the magnitude. Range: −(2^(N−1)−1) to +(2^(N−1)−1). Problem: two representations of zero (+0 = 0b00000000 and −0 = 0b10000000); addition requires separate sign handling logic. Rarely used now except in floating-point mantissas.
One’s complement: negative values obtained by inverting all bits. −5 in 8-bit one’s complement = NOT 0b00000101 = 0b11111010. Still has two zeros problem (0b00000000 and 0b11111111). Used in early systems; now obsolete.
Two’s complement won because: one unique zero, arithmetic works naturally with standard adder circuits, and negation is simple (invert + 1).
Fixed-Point and Floating-Point Values
Fixed-point: a binary number interpreted as having a decimal point at a fixed position. For a 16-bit value with 8 integer bits and 8 fractional bits (Q8.8 format):
- Bits 15–8: integer part (0–255)
- Bits 7–0: fractional part (0/256 to 255/256)
Value = integer_bits + fractional_bits / 256
Example: 0b0000001100110011 = 3 + 0x33/0x100 = 3 + 51/256 ≈ 3.199
Fixed-point is fast (uses integer arithmetic circuits) and predictable (no rounding surprises), but has limited range. Used in audio DSP, graphics, and embedded systems where performance matters more than range.
Floating-point (IEEE 754): stores numbers in the form ±mantissa × 2^exponent. A 32-bit float: 1 sign bit, 8 exponent bits, 23 mantissa bits. Range: approximately ±1.2×10^−38 to ±3.4×10^38 with about 7 decimal digits of precision.
Floating-point can represent an enormous range but has precision limitations: not all decimal fractions are exactly representable (0.1 in decimal ≈ 0.0999999… in float). Understanding this prevents a common class of programming errors.
Character Encodings
Text is stored as numeric codes for characters. The standard mappings:
ASCII (American Standard Code for Information Interchange): 7-bit encoding, values 0–127.
- 0–31: control characters (0=null, 9=tab, 10=newline, 13=carriage return)
- 32: space
- 48–57: digits ‘0’–‘9’ (ASCII ‘0’ = 0x30 = 48)
- 65–90: uppercase ‘A’–‘Z’ (ASCII ‘A’ = 0x41 = 65)
- 97–122: lowercase ‘a’–‘z’ (ASCII ‘a’ = 0x61 = 97)
- 33–47, 58–64, 91–96, 123–126: punctuation and symbols
Note: digit ‘0’ = 0x30, not 0x00. Converting digit character to numeric value: value = character − ‘0’ (subtract ASCII ‘0’ = 48). Converting lowercase to uppercase: subtract 32 (or clear bit 5): ‘a’ − 32 = ‘A’.
UTF-8: variable-width encoding for Unicode, backward compatible with ASCII for codepoints 0–127. Characters beyond ASCII use 2–4 bytes.
For hand-built systems and initial programming, 7-bit ASCII is sufficient and universally understood.
Bit Patterns as Multiple Types
The same 8-bit pattern 0b10110100 = 0xB4 could be:
- Unsigned integer: 180
- Signed integer (two’s complement): −76
- Two ASCII characters: interpreted as a compressed pair
- Four 2-bit fields: 10, 11, 01, 00
- A pixel: red component of an RGBA color
- An instruction byte in some CPU’s machine code
The meaning depends entirely on context. The hardware stores only the bits; software assigns the interpretation. This is why strong typing in high-level languages is valuable: it tracks the intended interpretation and prevents treating a pointer as an integer or a character as a signed count.
Understanding this fundamental ambiguity in bit patterns is essential for debugging at the hardware or assembly level, where raw hex values must be correctly interpreted to understand system state.