ID: 24876 Updated by: [EMAIL PROTECTED] Reported By: jeff at tmtrading dot com -Status: Open +Status: Bogus Bug Type: Math related Operating System: Redhat 8.0 PHP Version: 4CVS-2003-07-30 (stable) New Comment:
Round works fine, 4.045 rounded to 2 digits == 4.05. Not bug. Previous Comments: ------------------------------------------------------------------------ [2003-07-30 19:12:04] jeff at tmtrading dot com Actually, below would seem to be a better solution. What I'm trying to point out is that writing a round function in php and the php's standard funtion give two different answers. That is just plain wrong. There's probably a better way to fix it, but the patch below works for me (limited testing). --- php4-STABLE-200307151930/ext/standard/math.c 2003-01-16 07:08:59.000000000 -0700 +++ php4-STABLE-200307301930/ext/standard/math.c 2003-07-30 17:04:50.000000000 -0700 @@ -114,6 +114,7 @@ zval **value, **precision; int places = 0; double f, return_val; + double fuzz = 0.01; if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 2 || zend_get_parameters_ex(ZEND_NUM_ARGS(), &value, &precision) == FAILURE) { @@ -143,9 +144,9 @@ return_val *= f; if (return_val >= 0.0) - return_val = floor(return_val + 0.5); + return_val = floor((return_val + fuzz) + 0.5); else - return_val = ceil(return_val - 0.5); + return_val = ceil((return_val - fuzz) - 0.5); return_val /= f; RETURN_DOUBLE(return_val); ------------------------------------------------------------------------ [2003-07-30 18:57:44] jeff at tmtrading dot com Description: ------------ php: php4-STABLE-200307301930 gcc: 3.2 20020903 (Red Hat Linux 8.0 3.2-7) I tried to model the "myround" function after the c code. I am not a C coder but I managed to get php to output the correct result with the following _hack_. --- php/ext/standard/math.c 2003-01-16 07:08:59.000000000 -0700 +++ php/ext/standard/math.c 2003-07-30 16:23:44.000000000 -0700 @@ -114,6 +114,7 @@ zval **value, **precision; int places = 0; double f, return_val; + float fixme_val; if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 2 || zend_get_parameters_ex(ZEND_NUM_ARGS(), &value, &precision) == FAILURE) { @@ -142,10 +143,11 @@ f = pow(10.0, (double) places); return_val *= f; + fixme_val = (float) return_val; if (return_val >= 0.0) - return_val = floor(return_val + 0.5); + return_val = floor((double)(fixme_val + 0.5)); else - return_val = ceil(return_val - 0.5); + return_val = ceil((double)(fixme_val - 0.5)); return_val /= f; RETURN_DOUBLE(return_val); As you can see the patch is lame. Since I am not a C programmer I do not know how to figure out why this works vs. the original (it appears correct!). Reproduce code: --------------- $numbers = array(4.045, 5.055, 41.045, 51.055); foreach($numbers as $number) { printf("%f : %f : %f\n",$number, round($number,2), myround($number,2)); } function myround($value, $precision) { (int) $places = $precision; (double) $f; (double) $return_val = (double) $value; $f = pow(10.0, (double) $places); $return_val *= $f; if($return_val >= 0.0) $return_val = floor($return_val + 0.5); else $return_val = ceil($return_val - 0.5); $return_val /= $f; return $return_val; } Expected result: ---------------- [EMAIL PROTECTED] cli]$ ./php -n -f test.php 4.045000 : 4.050000 : 4.050000 5.055000 : 5.060000 : 5.060000 41.045000 : 41.050000 : 41.050000 51.055000 : 51.060000 : 51.060000 Actual result: -------------- [EMAIL PROTECTED] cli]$ ./php -n -f ./test.php 4.045000 : 4.040000 : 4.050000 5.055000 : 5.050000 : 5.060000 41.045000 : 41.050000 : 41.050000 51.055000 : 51.050000 : 51.060000 ------------------------------------------------------------------------ -- Edit this bug report at http://bugs.php.net/?id=24876&edit=1