From 67e55b273cef457f13f75bcf3753471138be3531 Mon Sep 17 00:00:00 2001 From: MarkBaker Date: Thu, 3 Dec 2015 01:55:18 +0000 Subject: [PATCH] Implement PHP_ROUND_UP and PHP_ROUND_DOWN options for round_updown.phpt() allowing the equivalent of ceil()/floor() with a precision argument --- ext/standard/basic_functions.c | 2 + ext/standard/math.c | 12 +++ ext/standard/php_math.h | 8 ++ ext/standard/tests/round_updown.phpt | 156 +++++++++++++++++++++++++++ 4 files changed, 178 insertions(+) create mode 100644 ext/standard/tests/round_updown.phpt diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index 5334e26439b78..17c11c347f150 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -3616,6 +3616,8 @@ PHP_MINIT_FUNCTION(basic) /* {{{ */ REGISTER_LONG_CONSTANT("PHP_ROUND_HALF_DOWN", PHP_ROUND_HALF_DOWN, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PHP_ROUND_HALF_EVEN", PHP_ROUND_HALF_EVEN, CONST_CS | CONST_PERSISTENT); REGISTER_LONG_CONSTANT("PHP_ROUND_HALF_ODD", PHP_ROUND_HALF_ODD, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PHP_ROUND_UP", PHP_ROUND_UP, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("PHP_ROUND_DOWN", PHP_ROUND_DOWN, CONST_CS | CONST_PERSISTENT); #if ENABLE_TEST_CLASS test_class_startup(); diff --git a/ext/standard/math.c b/ext/standard/math.c index 6059f3dd9bb28..ebd5ccd8af7b4 100644 --- a/ext/standard/math.c +++ b/ext/standard/math.c @@ -146,6 +146,18 @@ PHPAPI double _php_math_round(double value, int places, int mode) { return value; } + if (mode == PHP_ROUND_DOWN || mode == PHP_ROUND_UP) { + f1 = php_intpow10(places); + tmp_value = value * f1; + if (mode == PHP_ROUND_DOWN) { + tmp_value = floor(tmp_value); + } else { + tmp_value = ceil(tmp_value); + } + tmp_value = tmp_value / f1; + return tmp_value; + } + precision_places = 14 - php_intlog10abs(value); f1 = php_intpow10(abs(places)); diff --git a/ext/standard/php_math.h b/ext/standard/php_math.h index 7ceaf80b7c542..7b92a7f27a39f 100644 --- a/ext/standard/php_math.h +++ b/ext/standard/php_math.h @@ -171,4 +171,12 @@ PHP_FUNCTION(atanh); #define PHP_ROUND_HALF_ODD 0x04 #endif +#ifndef PHP_ROUND_UP +#define PHP_ROUND_UP 0x05 /* Always rounding, up == away from zero */ +#endif + +#ifndef PHP_ROUND_DOWN +#define PHP_ROUND_DOWN 0x06 /* Always rounding, down == towards zero */ +#endif + #endif /* PHP_MATH_H */ diff --git a/ext/standard/tests/round_updown.phpt b/ext/standard/tests/round_updown.phpt new file mode 100644 index 0000000000000..07f8868812947 --- /dev/null +++ b/ext/standard/tests/round_updown.phpt @@ -0,0 +1,156 @@ +--TEST-- +Test round() function : PHP_ROUND_UP/PHP_ROUND_DOWN modes +--FILE-- + +===Done=== +--EXPECTF-- +*** Testing round() : PHP_ROUND_UP/PHP_ROUND_DOWN modes *** + +3.45 rounded down to 0 precision is 3 (3) YES +3.5 rounded down to 0 precision is 3 (3) YES +3.55 rounded down to 0 precision is 3 (3) YES +-3.45 rounded down to 0 precision is -4 (-4) YES +-3.5 rounded down to 0 precision is -4 (-4) YES +-3.55 rounded down to 0 precision is -4 (-4) YES +345 rounded down to -1 precision is 340 (340) YES +350 rounded down to -1 precision is 350 (350) YES +355 rounded down to -1 precision is 350 (350) YES +-345 rounded down to -1 precision is -350 (-350) YES +-350 rounded down to -1 precision is -350 (-350) YES +-355 rounded down to -1 precision is -360 (-360) YES +345 rounded down to -2 precision is 300 (300) YES +350 rounded down to -2 precision is 300 (300) YES +355 rounded down to -2 precision is 300 (300) YES +-345 rounded down to -2 precision is -400 (-400) YES +-350 rounded down to -2 precision is -400 (-400) YES +-355 rounded down to -2 precision is -400 (-400) YES +0.345 rounded down to 1 precision is 0.3 (0.3) YES +0.35 rounded down to 1 precision is 0.3 (0.3) YES +0.355 rounded down to 1 precision is 0.3 (0.3) YES +-0.345 rounded down to 1 precision is -0.4 (-0.4) YES +-0.35 rounded down to 1 precision is -0.4 (-0.4) YES +-0.355 rounded down to 1 precision is -0.4 (-0.4) YES +0.345 rounded down to 2 precision is 0.34 (0.34) YES +0.35 rounded down to 2 precision is 0.35 (0.35) YES +0.355 rounded down to 2 precision is 0.35 (0.35) YES +-0.345 rounded down to 2 precision is -0.35 (-0.35) YES +-0.35 rounded down to 2 precision is -0.35 (-0.35) YES +-0.355 rounded down to 2 precision is -0.36 (-0.36) YES +1.23456789E+15 rounded down to -12 precision is 1.234E+15 (1.234E+15) YES +1.23456789E-15 rounded down to 18 precision is 1.234E-15 (1.234E-15) YES +-1.23456789E+15 rounded down to -12 precision is -1.235E+15 (-1.235E+15) YES +-1.23456789E-15 rounded down to 18 precision is -1.235E-15 (-1.235E-15) YES +1.23456789E+135 rounded down to -132 precision is 1.234E+135 (1.234E+135) YES +1.23456789E-135 rounded down to 138 precision is 1.234E-135 (1.234E-135) YES +-1.23456789E+135 rounded down to -132 precision is -1.235E+135 (-1.235E+135) YES +-1.23456789E-135 rounded down to 138 precision is -1.235E-135 (-1.235E-135) YES + +3.45 rounded up to 0 precision is 4 (4) YES +3.5 rounded up to 0 precision is 4 (4) YES +3.55 rounded up to 0 precision is 4 (4) YES +-3.45 rounded up to 0 precision is -3 (-3) YES +-3.5 rounded up to 0 precision is -3 (-3) YES +-3.55 rounded up to 0 precision is -3 (-3) YES +345 rounded up to -1 precision is 350 (350) YES +350 rounded up to -1 precision is 350 (350) YES +355 rounded up to -1 precision is 360 (360) YES +-345 rounded up to -1 precision is -340 (-340) YES +-350 rounded up to -1 precision is -350 (-350) YES +-355 rounded up to -1 precision is -350 (-350) YES +345 rounded up to -2 precision is 400 (400) YES +350 rounded up to -2 precision is 400 (400) YES +355 rounded up to -2 precision is 400 (400) YES +-345 rounded up to -2 precision is -300 (-300) YES +-350 rounded up to -2 precision is -300 (-300) YES +-355 rounded up to -2 precision is -300 (-300) YES +0.345 rounded up to 1 precision is 0.4 (0.4) YES +0.35 rounded up to 1 precision is 0.4 (0.4) YES +0.355 rounded up to 1 precision is 0.4 (0.4) YES +-0.345 rounded up to 1 precision is -0.3 (-0.3) YES +-0.35 rounded up to 1 precision is -0.3 (-0.3) YES +-0.355 rounded up to 1 precision is -0.3 (-0.3) YES +0.345 rounded up to 2 precision is 0.35 (0.35) YES +0.35 rounded up to 2 precision is 0.35 (0.35) YES +0.355 rounded up to 2 precision is 0.36 (0.36) YES +-0.345 rounded up to 2 precision is -0.34 (-0.34) YES +-0.35 rounded up to 2 precision is -0.35 (-0.35) YES +-0.355 rounded up to 2 precision is -0.35 (-0.35) YES +1.23456789E+15 rounded up to -12 precision is 1.235E+15 (1.235E+15) YES +1.23456789E-15 rounded up to 18 precision is 1.235E-15 (1.235E-15) YES +-1.23456789E+15 rounded up to -12 precision is -1.234E+15 (-1.234E+15) YES +-1.23456789E-15 rounded up to 18 precision is -1.234E-15 (-1.234E-15) YES +1.23456789E+135 rounded up to -132 precision is 1.235E+135 (1.235E+135) YES +1.23456789E-135 rounded up to 138 precision is 1.235E-135 (1.235E-135) YES +-1.23456789E+135 rounded up to -132 precision is -1.234E+135 (-1.234E+135) YES +-1.23456789E-135 rounded up to 138 precision is -1.234E-135 (-1.234E-135) YES + +===Done===