#24142 [Com]: round() does 5.045 to 5.04 instead of 5.05

From: Date: Wed, 16 Jul 2003 09:00:23 +0000
Subject: #24142 [Com]: round() does 5.045 to 5.04 instead of 5.05
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-44115@lists.php.net to get a copy of this message
ID: 24142 Comment by: webmaster at ragnarokonline dot de Reported By: infohata at firmos dot net Status: Bogus Bug Type: Zend Engine 2 problem Operating System: Linux PHP Version: 5.0.0-dev Assigned To: stas New Comment: The test-case hasn't been corrected for PHP 4.3.3-dev Previous Comments: ------------------------------------------------------------------------ [2003-06-16 14:16:12] sniper@php.net Should always test myself and not trust others: # /usr/src/web/php/php5/sapi/cli/php -n t.php 5.04499999999999992894573 5.04999999999999982236432 5.04999999999999982236432 5.05 No bug anywhere. ------------------------------------------------------------------------ [2003-06-16 14:00:55] 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-06-16 12:10:33] derick@php.net Stas, I was so free to assign this to you :) ------------------------------------------------------------------------ [2003-06-16 12:09:50] 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-12 02:45:09] 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. ------------------------------------------------------------------------ The remainder of the comments for this report are too long. To view the rest of the comments, please view the bug report online at http://bugs.php.net/24142 -- Edit this bug report at http://bugs.php.net/?id=24142&edit=1

« previous php.bugs (#44115) next »