The PHP doc answers this better than I could:
Floating point numbers have limited
precision. Although it depends on the
system, PHP typically uses the IEEE
754 double precision format, which
will give a maximum relative error due
to rounding in the order of 1.11e-16.
Non elementary arithmetic operations
may give larger errors, and, of
course, error progragation must be
considered when several operations are
compounded.
Additionally, rational numbers that
are exactly representable as floating
point numbers in base 10, like 0.1 or
0.7, do not have an exact representation as floating point
numbers in base 2, which is used
internally, no matter the size of the
mantissa. Hence, they cannot be
converted into their internal binary
counterparts without a small loss of
precision. This can lead to confusing
results: for example,
floor((0.1+0.7)*10) will usually
return 7 instead of the expected 8,
since the internal representation will
be something like
7.9999999999999991118....
So never trust floating number results
to the last digit, and never compare
floating point numbers for equality.
If higher precision is necessary, the
arbitrary precision math functions and
gmp functions are available.
Edit: Your question title asked how to fix. It's simple... rounding. $val = round($val, 2);