note 81824 added to function.round
| From: | timnotforspamshaw at mailNOSPAM dot usa dot com | Date: | Fri, 14 Mar 2008 17:02:30 +0000 |
| Subject: | note 81824 added to function.round | ||
| Groups: | php.notes | ||
| Request: | Send a blank email to php-notes+get-137070@lists.php.net to get a copy of this message | ||
Many people posting notes here are confused.
Do not assume that what you see for a floating point number is the actual value. The value 0.1 can
not be represented exactly in binary floating point, no matter how many bits are present in the
floating point representation, because 5 does not go into any power of 2. Most other fractions can
also not be represented exactly either.
For instance,
<?php
echo 0.285 + 0.0 - 0.285
printf("%.17f", 0.285) - 0.28499999999999998
?>
There is no problem with round(0.285) rounding in the incorrect direction; it is rounding in the
correct direction for the argument it is receiving. The problem is that the coder is not being
careful with tiny floating point errors that can creep in and become large when things are rounded.
For money, one solution is to always store things as an integer, e.g. in cents or mils (thousandths
of a monetary unit). Then there is no floating point rounding problem.
For other values, where floating point is necessary, I usually add a very small epsilon before
rounding, usually about 1e-6 less than the rounding digit. This causes things that look like they
should be rounded up, to actually round up.
Also, remember to never simply compare a floating point number against another number, even zero,
and expect the comparison to work as expected, because of these tiny errors. Always use a small
epsilon in the comparison. The direction of the epsilon depends on the intent of the comparison: $a
> $b becomes $a > $b + $epsilon, $a >= $b becomes $a >= $b - $epsilon, and $a == $b
becomes ($a <= $b + $epsilon && $a >= $b - $epsilon).
Please see
www.php.net/float
----
Server IP: 208.69.120.35
Probable Submitter: 66.214.49.84
----
Manual Page -- http://www.php.net/manual/en/function.round.php
Edit -- https://master.php.net/note/edit/81824
Del: integrated -- https://master.php.net/note/delete/81824/integrated
Del: useless -- https://master.php.net/note/delete/81824/useless
Del: bad code -- https://master.php.net/note/delete/81824/bad+code
Del: spam -- https://master.php.net/note/delete/81824/spam
Del: non-english -- https://master.php.net/note/delete/81824/non-english
Del: in docs -- https://master.php.net/note/delete/81824/in+docs
Del: other reasons-- https://master.php.net/note/delete/81824
Reject -- https://master.php.net/note/reject/81824
Search -- https://master.php.net/manage/user-notes.php