Inside a processor there are billions of transistors, and each one is just a switch. It conducts or it does not — high voltage or low. There is no reliable middle setting, because temperature, manufacturing tolerance and electrical noise would make ten distinguishable voltage levels unreadable at billions of cycles per second. So the entire machine counts in a system with exactly two digits. Every photograph, song, message and Java program on your computer is, physically, a very long pattern of switches. What makes the pattern mean something is an agreement about how to read it.
Bits, bytes and place value
A bit is one 0 or 1. Eight bits make a byte, which is the smallest chunk most systems can address individually. You already understand how binary numbers work, because you already understand place value: in decimal, 305 means three hundreds, no tens and five ones, and each column is worth ten times the one to its right because there are ten digits. Binary has two digits, so each column is worth twice the one to its right. The place values from the right are 1, 2, 4, 8, 16, 32, 64, 128. Nothing else about the arithmetic changes.
Binary to decimal, and back
To go from binary to decimal, write the place values above the bits and add up only the columns holding a 1. To go from decimal to binary, the division method is the one that is hardest to get wrong: divide by 2 repeatedly, writing down each remainder, then read the remainders from the bottom up.
| Divide by 2 | Quotient | Remainder |
|---|---|---|
| 214 ÷ 2 | 107 | 0 |
| 107 ÷ 2 | 53 | 1 |
| 53 ÷ 2 | 26 | 1 |
| 26 ÷ 2 | 13 | 0 |
| 13 ÷ 2 | 6 | 1 |
| 6 ÷ 2 | 3 | 0 |
| 3 ÷ 2 | 1 | 1 |
| 1 ÷ 2 | 0 | 1 |
Why hexadecimal exists
Binary is correct but unreadable — nobody dictates 11010110 over the phone without making a mistake. Hexadecimal is base 16, and because 16 is , exactly four bits make exactly one hex digit with no arithmetic carrying across the boundary. A byte becomes two characters, a colour becomes six, a memory address becomes eight. That is why every error code, MAC address and web colour you will ever see is written in hex. The digits above 9 are letters: A is 10, B is 11, C is 12, D is 13, E is 14, F is 15.
| Decimal | Binary (4-bit) | Hex |
|---|---|---|
| 0 | 0000 | 0 |
| 1 | 0001 | 1 |
| 2 | 0010 | 2 |
| 3 | 0011 | 3 |
| 4 | 0100 | 4 |
| 5 | 0101 | 5 |
| 6 | 0110 | 6 |
| 7 | 0111 | 7 |
| 8 | 1000 | 8 |
| 9 | 1001 | 9 |
| 10 | 1010 | A |
| 11 | 1011 | B |
| 12 | 1100 | C |
| 13 | 1101 | D |
| 14 | 1110 | E |
| 15 | 1111 | F |
The units ladder, and the 1024 problem
Above the byte the prefixes climb, but there are two competing sets of them and that difference causes a question that appears in every course like this one. Storage manufacturers and network engineers use decimal prefixes: a kilobyte is 1000 bytes. Memory sizing and most operating systems use binary prefixes: 1024 bytes, because memory is addressed in powers of two. The proper names for the binary ones are kibibyte, mebibyte and gibibyte, but many programs still label them KB, MB and GB.
- 1 kB = 1 000 bytes
- 1 MB = 1 000 000 bytes
- 1 GB = 1 000 000 000 bytes
- Used by drive makers, network speeds and the SI standard
- 1 KiB = 1 024 bytes
- 1 MiB = 1 048 576 bytes
- 1 GiB = 1 073 741 824 bytes
- Used for RAM sizing and by many operating systems
Turning real things into numbers
A bit pattern means nothing on its own. The byte 01000001 is the number 65, the letter A, a very dark red, or a fragment of a machine instruction, and which one it is depends entirely on what the program reading it expects. ASCII assigns a number from 0 to 127 to each English character, fitting in 7 bits stored inside one byte. The layout is deliberate: A is 65 and a is 97, exactly 32 apart, so flipping one bit changes case. The digit characters start at 48, so subtracting 48 from a digit's code gives the number it stands for.
ASCII covers English and nothing else, which is why Unicode exists. Unicode assigns a code point to every character in every writing system, plus emoji. UTF-8 encodes those code points using one to four bytes each, and its first 128 values are deliberately identical to ASCII, so every ASCII file is already valid UTF-8. Images work by the same idea in two dimensions: a grid of pixels, each pixel storing a colour as a number, with colour depth deciding how many bits each pixel gets. Sound is the same idea in one dimension: an analog waveform sampled thousands of times a second, each sample stored as a number.
| Data type | What is actually stored | What drives the size |
|---|---|---|
| Whole number | A fixed-width binary pattern | How many bits the type reserves |
| Text (ASCII) | One byte per character | Number of characters |
| Text (UTF-8) | 1–4 bytes per character | Which characters are used |
| Bitmap image | One colour number per pixel | Width × height × colour depth |
| Audio (PCM) | One number per sample per channel | Sample rate × bit depth × channels × seconds |
Where this shows up in Java
This is not background trivia — it is the reason Java has more than one kind of whole number. Every primitive type is a promise about exactly how many bits the variable gets, and a fixed number of bits can only hold a fixed number of distinct values. Java's integer types are signed, which means one bit's worth of the range is given over to negatives, so an n-bit signed type runs from to .
| Java type | Bits | Range | Use it when |
|---|---|---|---|
| byte | 8 | −128 to 127 | Raw file or network data |
| short | 16 | −32 768 to 32 767 | Rarely; memory-tight arrays |
| int | 32 | −2 147 483 648 to 2 147 483 647 | The default choice for whole numbers |
| long | 64 | about ±9.2 × 10¹⁸ | Counts of milliseconds, very large totals |
| char | 16 | 0 to 65 535 (a UTF-16 code unit) | A single character |
| boolean | 1 logically | true or false | A yes/no flag |
int big = 2147483647; // this is Integer.MAX_VALUE
System.out.println(big + 1); // prints -2147483648, NOT 2147483648
long safe = 2147483647L; // the L makes it a long literal
System.out.println(safe + 1);// prints 2147483648
char letter = 'A';
int code = letter; // 65 - a char really is a number
System.out.println((char)(letter + 32)); // prints a