Everything in computing starts with one simple idea: electricity can be ON or OFF. We label these states 1 and 0 — a single bit, the smallest unit of information that can exist.
Analogy: A bit is like a yes-or-no question. Alone it's trivial, but ask 20 in sequence and you can identify almost anything — that's the logic behind "20 Questions." Enough bits combined can represent anything.
Why binary? Humans use base 10 because we have ten fingers. Computers use binary (base 2) because transistors have exactly two reliable electrical states: ON or OFF. It's not an arbitrary choice — two states are simply the most stable thing to engineer in hardware.
Bit Groups
Four bits form a nibble (16 values). Eight bits form a byte (256 values). The byte is the smallest addressable unit of memory in most architectures — you can't read a single bit from RAM, you read at least one byte. A byte can encode a number 0–255, a character like 'A' (ASCII value 65 = 01000001), or one channel of a color value.
Analogy: Bits are like Morse code. Just two symbols — dot and dash — encode the entire English language. 0s and 1s can encode everything: text, images, video, music, programs.
Representing Negative Numbers — Two's Complement
A raw byte holds 0–255 (unsigned). Programs also need negative numbers. The standard encoding is two's complement: the most-significant bit (MSB) acts as a sign bit, and the pattern wraps around so that the same adder circuit handles both signed and unsigned arithmetic without modification.
To negate any value: flip all bits, then add 1.
5=0000 0101- Flip bits:
1111 1010 - Add 1:
1111 1011= −5
Why this works: 5 + (−5) in hardware produces 0000 0000 — the carry out of the MSB is discarded and the result is zero. No separate subtraction circuit needed.
Integer overflow happens when arithmetic exceeds the representable range. For a signed 8-bit value, adding 1 to 127 wraps to −128. The hardware doesn't raise an error — bits just roll over — which is why C programs can produce silently wrong results. Languages like Rust and Swift make overflow a compile-time or checked runtime error by default.
Floating Point — IEEE 754
Integers are exact but limited in range. Floating-point numbers trade exactness for the ability to represent both very large and very small values. The IEEE 754 standard (used by every modern CPU and language) defines two formats:
The value is: ± 1.mantissa × 2^(exponent − bias)
The critical consequence: most decimal fractions have no exact binary representation. 0.1 + 0.2 evaluates to 0.30000000000000004 in every language that uses IEEE 754 doubles. This isn't a language bug — it's fundamental to binary floating point. This is why financial software uses fixed-point arithmetic or decimal types (e.g., Python's Decimal, Java's BigDecimal), never floats.
Special values encoded in IEEE 754 include +Infinity, −Infinity, and NaN (Not a Number, result of 0/0 or sqrt(−1)).
Text Encoding — From ASCII to Unicode
Early computers assigned each character a 7-bit number (ASCII: 128 characters — English letters, digits, punctuation, control codes). 8-bit bytes allowed 256-character extensions, but different regions adopted incompatible extensions, producing encoding chaos.
Unicode defines a universal code space of over 143,000 characters covering all human writing systems. UTF-8 is the dominant encoding: ASCII characters use 1 byte unchanged; other code points use 2–4 bytes. It is backward-compatible with ASCII and is the default for HTML, HTTP, JSON, and most modern file formats.
When you read a file or network stream and see "garbled text," the root cause is almost always an encoding mismatch — the bytes are being interpreted with the wrong encoding table.
Endianness
Multi-byte values must be laid out as a sequence of bytes in memory. The ordering convention is called endianness:
- Little-endian: least-significant byte stored first. Intel x86/x64 and ARM (in LE mode) use this. The 32-bit value
0x01020304is stored as04 03 02 01in memory. - Big-endian: most-significant byte first. Used by most network protocols (TCP/IP, HTTP headers) — also called "network byte order."
When writing network code or parsing binary file formats, you must convert between host byte order and network byte order (htons, htonl in C; ByteOrder in Java). Ignoring endianness is a common source of subtle bugs in serialization and protocol code.
Hexadecimal
Binary strings are hard to read. Hexadecimal (base 16) compresses them: every four bits map to one hex digit (0–9, then A–F). A 16-bit address shrinks from 16 digits to 4.