php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #24142 round() does 5.045 to 5.04 instead of 5.05
Submitted: 2003-06-12 02:28 UTC Modified: 2006-01-15 15:10 UTC
From: infohata at firmos dot net Assigned:
Status: Closed Package: Scripting Engine problem
PHP Version: 5.0.0-dev OS: Linux
Private report: No CVE-ID: None
 [2003-06-12 02:28 UTC] infohata at firmos dot net
Description:
------------
I am using a webhosting service of bbdsoft (www.firmos.net) so I don't know exact OS and configuration of PHP.INI, but this bug is
independent of any config or OS, it's about round() function - it has a big bug rounding floats!!

All the details and what's have to be is written below in the source code and it's comments:)

Well, I saw other reports, and I think YOU SHOULD FIX THIS IN ANY CASE AND AS FAST AS POSSIBLE!!!

Reproduce code:
---------------
// at the start of the return code these variables has values:
$skerd_svoris = 1;
$rows_kriu_kain00[0] = 5;
$rows_kriu_kkoef[0] = 0.9;

// return code:
return sprintf("%1.2f", round($skerd_svoris*round($rows_kriu_kain00[0]*(1+($rows_kriu_kkoef[0]/100)), 2), 2));

// if the code is changed to:
// return sprintf("%1.2f", round($skerd_svoris*round($rows_kriu_kain00[0]*(1+($rows_kriu_kkoef[0]/100))+0.000001, 2), 2));
// all goes OK; so the problem is that if the number is 5.045, rounded it will be 5.04, but if it is 5.045001 - rounded it will be 5.05. I think You understood what I want to say:)

Expected result:
----------------
5.05

Actual result:
--------------
5.04

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2003-06-12 02:45 UTC] rasmus@php.net
This is expected behaviour.  When rounding on exact halves we round down on evens and up on odds.  If you want to always force it in one direction on a .5 (or .05 in your case) add or substract a tiny fuzz factor.  The reason behind rounding half the values down and the other half up is to avoid the classical banking problem where if you always rounded down you would be stealing money from your customers, or if you always rounded up you would end up over time losing money.  By averaging it out through evens and odds you statistically break even.  If you want to learn more, search the web for terms such as "round to even" or "banker's rounding" and you will find that most languages actually do it this way.
 [2003-06-16 12:09 UTC] derick@php.net
hmm, actually this changed between PHP 4.2.2, PHP 4.2.3 an PHP 4.3.0:

[derick@kossu derick]$ cat foo.php   
<?php
$mul = 1;
$one = 5;
$two = 0.9;

echo sprintf("%1.2f", round($mul * round($one * (1 + ($two / 100)), 2), 2));
?>

[derick@kossu derick]$ php-4.2.2 foo.php 
5.04

[derick@kossu derick]$ php-4.2.3 foo.php 
5.05zend_hash.c(98) : Bailed out without a bailout address!

[derick@kossu derick]$ php-4.3.0 foo.php 
5.05

[derick@kossu derick]$ php-4.3.0dev foo.php 
5.05

[derick@kossu derick]$ php-5.0.0dev foo.php 
5.04

So something is definitely screwed in the PHP_4_3 branch

Derick
 [2003-06-16 14:00 UTC] sniper@php.net
With this script:

<?php

$mul = 1;
$one = 5;
$two = 0.9;

ini_set("precision", 24);

$res = 5 * (1 + (0.9 / 100));
$bar = round($res, 2);
$foo = round(1 * $bar, 2);

echo $res, "\n", $bar, "\n", $foo, "\n";

echo sprintf("%1.2f", $foo);

?>

Result with PHP 4.3.3-dev:
5.04499999999999992894573
5.04999999999999982236432
5.04999999999999982236432
5.05

Result with PHP 4.2.3:
5.04499999999999992894573
5.04000000000000003552714
5.04000000000000003552714
5.04

Nokia 6120 (the $res):
5.045

TI-32:
5.045

With pen and paper:
5.045

Round 5.045 with precision of 2 == 5.05

So I think PHP 4.3.2 actually works as expected 
and anything before (and after, PHP 5? :) doesn't.

Reclassified as ZE2 bug.


 [2003-08-09 11:16 UTC] iliaa@php.net
This bug has been fixed in CVS.

In case this was a PHP problem, snapshots of the sources are packaged
every three hours; this change will be in the next snapshot. You can
grab the snapshot at http://snaps.php.net/.
 
In case this was a documentation problem, the fix will show up soon at
http://www.php.net/manual/.

In case this was a PHP.net website problem, the change will show
up on the PHP.net site and on the mirror sites in short time.
 
Thank you for the report, and for helping us make PHP better.


 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Tue Mar 19 09:01:30 2024 UTC