From: Andrei Zmievski Date: Wed, 17 May 2000 12:50:04 +0000 (+0000) Subject: @- Improved round() to allow specification of rounding precision. X-Git-Tag: php-4.0.0~80 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=08ff225a467c05c34a38aceccdb67fe1411fd185;p=php @- Improved round() to allow specification of rounding precision. @ (Andrei, Todd Kirby ) --- diff --git a/configure.in b/configure.in index 9d8e76ba2b..be04a2c87a 100644 --- a/configure.in +++ b/configure.in @@ -346,7 +346,6 @@ putenv \ random \ rand_r \ regcomp \ -rint \ setitimer \ setlocale \ setsockopt \ diff --git a/ext/standard/math.c b/ext/standard/math.c index 3d15905823..5671c9426a 100644 --- a/ext/standard/math.c +++ b/ext/standard/math.c @@ -101,45 +101,59 @@ PHP_FUNCTION(floor) { } /* }}} */ -/* {{{ proto int round(double number) - Returns the rounded value of the number */ -#ifndef HAVE_RINT -/* emulate rint */ -inline double rint(double n) -{ - double i, f; - f = modf(n, &i); - if (f > .5) - i++; - else if (f < -.5) - i--; - return i; -} -#endif +/* {{{ proto int round(double number, int precision) + Returns the number rounded to specified precision. */ PHP_FUNCTION(round) { - zval **value; - - if (ARG_COUNT(ht) != 1 || zend_get_parameters_ex(1, &value) == FAILURE) { + zval **value, **precision; + int places = 0; + double f, return_val; + + if (ZEND_NUM_ARGS() < 1 || ZEND_NUM_ARGS() > 2 || + zend_get_parameters_ex(ZEND_NUM_ARGS(), &value, &precision) == FAILURE) { WRONG_PARAM_COUNT; } + if (ZEND_NUM_ARGS() == 2) { + convert_to_long_ex(precision); + places = (int) Z_LVAL_PP(precision); + } + convert_scalar_to_number_ex(value); - if ((*value)->type == IS_DOUBLE) { - double d; - d=rint((*value)->value.dval); - if(d==0.0) d=0.0; /* workaround for rint() returning -0 instead of 0 */ - RETURN_DOUBLE(d); - } else if ((*value)->type == IS_LONG) { - RETURN_DOUBLE((double)(*value)->value.lval); + switch (Z_TYPE_PP(value)) { + case IS_LONG: + /* Simple case - long that doesn't need to be rounded. */ + if (places >= 0) { + RETURN_DOUBLE((double) Z_LVAL_PP(value)); + } + /* break omitted intentionally */ + + case IS_DOUBLE: + return_val = (Z_TYPE_PP(value) == IS_LONG) ? Z_LVAL_PP(value) : Z_DVAL_PP(value); + + f = pow(10.0, 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_DOUBLE(return_val); + break; + + default: + RETURN_FALSE; + break; } - RETURN_FALSE; } - /* }}} */ + + /* {{{ proto double sin(double number) Returns the sine of the number in radians */