Everybody who has ever programmed with almost any programming language,
and even many people who never have (but use computers) have heard the
story: Fractional and real numbers are approximated in computers by using
the so-called floating point numbers, and these numbers suffer from
accuracy problems which means that direct comparisons (ie. if you have
two floating point numbers calculated by two different means, comparing
them with a direct "is equal to" operator will often give the wrong answer)
should be avoided and instead a ranged comparison using an epsilon value
should be used instead (ie. "`abs(a-b)<epsilon`

").

This is basically true. The problem with floating point numbers is that they only have a limited number of bits to represent such a vast set of numbers as the reals, and thus they are prone to rounding errors when calculations are performed with them. The typical example is: Make a loop which sums 0.1 ten times to a variable (which initial value is zero), and then compare the result to 1.0. In theory the comparison should give true, because ten times 0.1 is 1.0. However, any programming language using regular floating point numbers will give false as the result of the comparison.

This is because the value 0.1 cannot be represented accurately with floating point numbers used by computers (this is related to the fact that these floating point numbers use base-2 numbers instead of base-10, as 0.1 is). The reason is the same why the value of the division 1/3 cannot be represented accurately with decimal representation (only a finite approximation can be represented, for example "0.333333333", which is close, but not equal). Thus when you start adding 0.1 to itself this slight rounding error will show itself in the end result, making it not equal to 1.0.

What amuses me, however, are the misconceptions that this phenomenon causes in some people.

Apparently some people think that floating point numbers suffer from
some kind of Heisenberg uncertainty principle: They never have an
*exact* value, but only a value which is close to it. It's like
the orbit of an electron around an atom: The electron is never in an
exact place, but somehow distributed around that place with a certain
probability. Thus you can never trust a floating point number to have
some *exact* value, you can only know with a high degree of
probability that it's inside a range.

Of course this is BS, and shows a great lack of understanding about how computers work. Computers use bits, and bits are either 0 or 1, and they stay like that until they are explicitly changed. They do not hover randomly somewhere in-between. If a bit has the value 1, then it has the value 1, exactly, and nothing else, until it's changed explicitly. In other words, bits are completely deterministic and predictable.

A floating point value consists of bits. Nothing more, nothing less. Thus a floating point value, by extension, is also determinstic and predictable, and it doesn't change value unless explicitly made to, and it doesn't hover in any in-between state like an electron around in an atomic orbit. You can read every single individual bit in a floating point value, and they will form an exact, accurate and deterministic representation of that floating point value. There's no Heisenberg uncertainty principle.

What these people confuse is the fact that *rounding errors*
caused by a limited number of bits used to represent the value will make
the result of many operations to become inexact. It's nothing more than
that. There's no quantum uncertainty here. It's just a rounding error,
nothing more, nothing less.

A floating point number *can* be used to represent an *exact*
numerical value. For example, the value 1.0 can be represented *exactly*
with a floating point variable. It's not "something very close to 1.0", it's
"*exactly* 1.0". There's no uncertainty there.

What *can* happen, as mentioned earlier, is that when you are
performing some calculations which in theory should give 1.0 you end up
having something very close but nevertheless not equal. This is not because
of any uncertainty principle nor because 1.0 couldn't be represented
accurately. It's simply because rounding errors during the calculations
caused the end result to be different.

To understand this with an example, let's use decimal representation with a limited amount of decimals, let's say 8. We represent the value of "1/3" in our decimal representation, which would thus be "0.33333333". Now we sum this value with itself two times. The first time we get "0.66666666", and the second time we get "0.99999999". We know from theory that 1/3+1/3+1/3 sould give us 1.0. However, when we compare "0.99999999" to "1.0" we see that they are not equal.

This is exactly the same phenomenon which happens with floating point numbers and the value 0.1 (instead of 1/3).

For the same reason things like "square root of 100" might not give
*exactly* 10. Not because 10 cannot be represented accurately,
but because the calculations required to calculate the square root of 100
may carry some rounding errors along the way.