Re: Bug #2835 Updated: floor (8.28 * 100) = 8.27
| From: | Zeev Suraski | Date: | Fri, 26 Nov 1999 18:00:55 +0000 |
| Subject: | Re: Bug #2835 Updated: floor (8.28 * 100) = 8.27 | ||
| References: | 1 | Groups: | php.dev |
| Request: | Send a blank email to php-dev+get-13150@lists.php.net to get a copy of this message | ||
In fact, you're wrong and you should realize that as soon as possible,
since none of the other applications you specified handles this situation
any better than PHP does (Oracle & MySQL included). A small test to
illustrate this:
mysql> select floor(8.17*100);
+-----------------+
| floor(8.17*100) |
+-----------------+
| 816 |
+-----------------+
1 row in set (0.00 sec)
Basic numeric analysis knowledge will tell you that computers represent
floating point numbers with limited accuracy. You often pay for this
limited accuracy in loss of significant digits if you don't watch your
step.
PHP's behavior is the same behavior you should expect from any other
computer language or program. It affects many other programs and aspects
in computer science.
Did you know, for example, that ANSI SQL doesn't allow you to give
'field=value' conditions in where clauses, if field is a floating point
number? You're always supposed to replace such clauses with
'field>min_limit and field<max_limit'.
Last illustrative example:
---
mysql> create table t_float (f float(2));
Query OK, 0 rows affected (0.08 sec)
mysql> insert into t_float (f) values (8.17);
Query OK, 1 row affected (0.00 sec)
mysql> select * from t_float where f=8.17;
Empty set (0.00 sec)
mysql> select * from t_float where f<8.171 and f>8.169;
+------+
| f |
+------+
| 8.17 |
+------+
1 row in set (0.00 sec)
---
My best recommendation for you is to stop trusting all of your computer
software when it comes to this issue, since most probably none of them
handles it the way you want (even though it may sometimes appear they do -
half of the cases would appear to be handled correctly!). This is
especially true if it concerns money.
Zeev
On 26 Nov 1999, Bug Database wrote:
> ID: 2835
> User Update by: aulbach@unter.franken.de
> Status: Closed
> Bug Type: Misbehaving function
> Description: floor (8.28 * 100) = 8.27
>
> There are some things which I will say to this good
> explanation:
>
> 1. This was of course clear for me, why this happens.
> But, sorry, Ramus, I'm not sharing your opinion, that
> you have to take care about rounding problems by yourself.
> In my eyes this keeps an error: The function doesn't do,
> what you expect and the results could be very ugly.
> See down.
>
> 2. The float number was printed out as "828" and not as
> "827.99999999999999999".
> So there must be an explizit float conversion, which does
> it "right".
>
> 3. Ok, I understand, why round(9.5) is not 10,
> but every simple pocket calculator does this simple
> thing "right".
>
> [Or Oracle for example:
> SQL> select trunc(8.28*100.0,0) from dual;
>
> TRUNC(8.28*100,0)
> -----------------
> 828
>
> mySQL of course too.]
>
> 4. For this business applications this behavior of the database
> mow saved me my live, cause I could see, if my change in the program
> works right: The resulting difference has been above 450
> Deutschmark (about $ 200) - this happens when you
> calculate about 400,000 operations with this small error.
>
> If you make this little error every day over a
> year you pay about $60,000 too much (or too less).
>
>
>
>
> Full Bug description available at: http://bugs.php.net/?id=2835
>
>
> --
> PHP Development Mailing List <http://www.php.net/>
> To unsubscribe, e-mail: php-dev-unsubscribe@lists.php.net
> For additional commands, e-mail: php-dev-help@lists.php.net
> To contact the list administrators, e-mail: php-list-admin@lists.php.net
>
--
-----------------------------------------------------
Zeev Suraski <zeev@zend.com> http://www.zend.com/