Binary
Binary uses only two symbols: 0 and 1, which is why it may also be called base 2. It’s the number system computers use to store data. A transistor may contain electrons (1) or it may not (0).
Here’s how binary numbers count, compared to decimal:
| Binary (base 2) | Decimal (base 10) |
|---|---|
| 0 | 0 |
| 1 | 1 (2^0) |
| 10 | 2 (2^1) |
| 11 | 3 |
| 100 | 4 (2^2) |
| 101 | 5 |
| 110 | 6 |
| 111 | 7 |
| 1000 | 8 (2^3) |
| 1001 | 9 |
| 1010 | 10 |
| 1011 | 11 |
| 1100 | 12 |
| 1101 | 13 |
| 1110 | 14 |
| 1111 | 15 |
| 10000 | 16 (2^4) |
A bit is a single binary digit, either 0 or 1.
A byte is 8 bits. For example, 11111111 (one byte of all 1s) equals 255 in decimal. 8 bytes = 64 bits.
Bit-width in computers
When we say a computer is 32-bit or 64-bit, we mean that its CPU registers are 32 or 64 bits wide. The width of a register determines the largest number it can store directly.
- A 32-bit register can store numbers from
0to11111111 11111111 11111111 11111111(decimal4,294,967,295, or2^32 - 1). - A 64-bit register can store numbers from
0to11111111 11111111 11111111 11111111 11111111 11111111 11111111 11111111(decimal18,446,744,073,709,551,615, or2^64 - 1).
Signed vs unsigned integers
Unsigned integers can only represent non-negative numbers, ranging from:
0 to (2^n - 1) where n is the number of bits.
Signed integers can represent both positive and negative numbers, using a system called two’s complement. In two’s complement, the first bit is the sign bit:
0means positive1means negative
This leaves n - 1 bits for the magnitude.
Examples for signed 32-bit integers:
01111111 11111111 11111111 11111111 = 2147483647
00000000 00000000 00000000 00000001 = 1
00000000 00000000 00000000 00000000 = 0
10000000 00000000 00000000 00000000 = -2147483648
10000000 00000000 00000000 00000001 = -2147483647
11111111 11111111 11111111 11111111 = -1Examples for unsigned 32-bit integers:
00000000 00000000 00000000 00000001 = 1
00000000 00000000 00000000 00000000 = 0
01111111 11111111 11111111 11111111 = 2147483647
10000000 00000000 00000000 00000000 = 2147483648
10000000 00000000 00000000 00000001 = 2147483649
11111111 11111111 11111111 11111111 = 4294967295Floating point numbers
Integers are exact in binary, but fractional numbers are not. A float is stored in scientific notation: a sign bit, an exponent, and a mantissa, roughly ±mantissa × 2^exponent:
Mantissa (noun) man·tis·sa
The part of a logarithm to the right of the decimal point
| Type | Bits | Sign | Exponent | Mantissa |
|---|---|---|---|---|
| Single (float) | 32 | 1 | 8 | 23 |
| Double (double) | 64 | 1 | 11 | 52 |
Just like 1/3 cannot be written exactly in decimal, most decimal fractions cannot be written exactly in binary. Binary can only represent sums of powers of two, so 0.1 becomes a repeating binary fraction:
0.1 = 0.0001100110011001100110011...The value is rounded to the nearest representable mantissa, and the rounding errors accumulate across operations:
0.1 + 0.2 = 0.30000000000000004not 0.3. This is why comparing floats with == is unreliable, and why calculators have to round their results before displaying them: showing the raw value would print 0.30000000000000004 instead of 0.3. Getting that right is one of the classic challenges of implementing a calculator.
Examples
Single precision (float), 32 bits, parsed as (-1)^sign × 1.mantissa × 2^(exponent - 127):
00111111 10000000 00000000 00000000 = (-1)^0 × 1.000000 × 2^0 = 1.0
00111111 00000000 00000000 00000000 = (-1)^0 × 1.000000 × 2^-1 = 0.5
00111110 10000000 00000000 00000000 = (-1)^0 × 1.000000 × 2^-2 = 0.25
00111101 10000000 00000000 00000000 = (-1)^0 × 1.000000 × 2^-3 = 0.125
00111101 00000000 00000000 00000000 = (-1)^0 × 1.000000 × 2^-4 = 0.0625
00111110 11001100 11001100 11001101 = (-1)^0 × 1.4CCCCD × 2^-2 = 0.4
00111110 01001100 11001100 11001101 = (-1)^0 × 1.4CCCCD × 2^-3 = 0.2
00111110 10011001 10011001 10011010 = (-1)^0 × 1.19999A × 2^-2 = 0.3
00111111 00011001 10011001 10011010 = (-1)^0 × 1.19999A × 2^-1 = 0.6
00000000 00000000 00000000 00000000 = 0 (special case)
00110101 10000110 00110111 10111101 = (-1)^0 × 1.0637BD × 2^-20 = 0.000001
10111111 10000000 00000000 00000000 = (-1)^1 × 1.000000 × 2^0 = -1.0
01001111 00000000 00000000 00000000 = (-1)^0 × 1.000000 × 2^31 = 2147483648The powers of two (1, 0.5, 0.25, 0.125, 0.0625) are exact: their mantissas are all zeros and only the exponent changes. The rest are rounded, and the repeating 1100/1001 mantissa patterns are the binary tails of fractions like 1/3 and 1/10. Note that 2147483647 as a float rounds up to 2147483648 (2^31).
Double precision (double), 64 bits, parsed as (-1)^sign × 1.mantissa × 2^(exponent - 1023):
00111111 10111001 10011001 10011001 10011001 10011001 10011001 10011010 = (-1)^0 × 1.999999999999A × 2^-4 = 0.1
00111111 11001001 10011001 10011001 10011001 10011001 10011001 10011010 = (-1)^0 × 1.999999999999A × 2^-3 = 0.2
00111111 11010011 00110011 00110011 00110011 00110011 00110011 00110011 = (-1)^0 × 1.3333333333333 × 2^-2 = 0.3
00111111 11010011 00110011 00110011 00110011 00110011 00110011 00110100 = (-1)^0 × 1.3333333333334 × 2^-2 = 0.30000000000000004 (0.1 + 0.2)0.3 and 0.1 + 0.2 differ by exactly one bit in the last position: that single bit is the whole 0.00000000000000004.