binary number representation
We write everyday numbers in base ten: the string 305 means 3 hundreds, 0 tens and 5 ones, because each position is worth ten times the one to its right. A computer stores numbers using only two symbols, 0 and 1, so it uses the same idea with a base of two instead of ten. This is binary, and it is the alphabet underneath every integer and every real number a machine ever touches.
In binary each position is a power of 2. The bits 1011 mean 1*2^3 + 0*2^2 + 1*2^1 + 1*2^0 = 8 + 0 + 2 + 1 = 11. The same positional trick extends past the binary point: 0.101 means 1*2^(-1) + 0*2^(-2) + 1*2^(-3) = 1/2 + 1/8 = 0.625. To convert a whole number TO binary you repeatedly divide by 2 and read the remainders bottom-up; to convert a fraction you repeatedly multiply by 2 and read the overflow bits top-down. Hardware adds, subtracts and shifts these bit strings directly.
The catch is that a finite string of bits can name only a finite, exact set of numbers, and which numbers those are depends on the base. One tenth, 0.1, is a clean terminating decimal but in binary it is the endlessly repeating 0.0001100110011..., so no finite computer word holds 0.1 exactly. That single fact is the seed of nearly every floating-point surprise: the value stored for 0.1 is a nearby binary number, not 0.1 itself.
Decimal 13 -> divide by 2: 13->6 r1, 6->3 r0, 3->1 r1, 1->0 r1; reading remainders upward gives 1101, and indeed 8+4+0+1 = 13. But decimal 0.1 -> multiply by 2 forever: 0.2(0), 0.4(0), 0.8(0), 1.6(1), 1.2(1), 0.4(0)... and the pattern never closes, so 0.1 has no finite binary form.
Whole numbers always terminate in binary; many friendly decimals do not.
A number is exactly representable in base 2 with finitely many bits only if it is an integer times a (possibly negative) power of two; 0.5, 0.25 and 0.75 are exact, but 0.1, 0.2 and 0.3 are not.