Consider what the individual digits of a number like 12.34 mean. Its value is $1\cdot10^1 + 2\cdot10^0 + 3\cdot10^{-1} + 4\cdot10^{-2}$. This is just what you learned in elementary school about the "ones place" and the "tens place," but written out in a more formal mathematical notation. Computers handle floating point numbers the same way, only they are far better at base 2 than they are at base 10, so they do the exact same process in binary. 5.25 gets broken into $1\cdot2^1 + 0\cdot2^1 + 1*\cdot2^0 + 0\cdot2^{-1} + 1\cdot2^{-2}$. If I were to rewrite it in the normal decimal form, but use base 2 values instead of base 10, $5.25_{10}$ would be written as $101.01_2$ (The base is notated here with a subscript, which is a very common notation to use when you are working with different bases. It helps keep the numbers straight). This is how computers typically approach floating point numbers.
If I ask you what 1/3 is as a decimal, you'd say something like $0.33333..._{10}$ However, if you kept writing 3's, youd run out of space, so you'd probably say "it's close to $0.33333_{10}$." Computers do the same thing. While 1/2 in base2 is $0.1_2$ and 1/8 is $0.001_2$ in base 2, not all numbers work out so cleanly. In particular 3/10 ($0.3_{10}$ in decimal) is equal to $0.010011001100..._2$ which must be rounded. It is these rounding errors that are causing the unusual effects you see.
As a general rule, one should never rely on exact equivalence with ==
to determine if two floating point numbers are equal, due to these rounding errors. One always compares them with some tolerance.
Many CPUs have a "decimal" mode for their floating point numbers which use base 10 instead of base 2. This can be slower, or lower precision, but it is a popular solution in situations like banking, where exact handling of fractions of a penny have to match up exactly. Since it is natural for us to watch for rounding errors in decimal, this causes the numbers to behave more intuitively. However, this has generally gone by the wayside. Almost everyone uses the normal IEE-754 binary representation of floating point numbers, because it is a very well rounded format. Those who need exactness often use fixed point math instead, which guarantees exact results using integer arithmetic.