From b152633ecb2030e2de1f83d2d42193185ea1bc21 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Sat, 9 Sep 2017 15:43:02 +0200 Subject: Scale support for bcmod() As of commit 90dcbbe (PHP-7.2+) bcmod() supports non-integral parameters as well. Since formerly only integer modulus has been supported, it did not make much sense to cater to the scale with regard to the result. However, now it does for consistency with other BCMath operations. Therefore, we add support for an optional `scale` parameter and fall back to the default scale (`bcmath.scale`) as usual. --- ext/bcmath/bcmath.c | 21 +++++++++++++++++---- ext/bcmath/tests/bcmod.phpt | 4 ++-- ext/bcmath/tests/bcmod_error1.phpt | 4 ++-- 3 files changed, 21 insertions(+), 8 deletions(-) diff --git a/ext/bcmath/bcmath.c b/ext/bcmath/bcmath.c index e8b87dceff..fdabb41066 100644 --- a/ext/bcmath/bcmath.c +++ b/ext/bcmath/bcmath.c @@ -60,9 +60,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_bcdiv, 0, 0, 2) ZEND_ARG_INFO(0, scale) ZEND_END_ARG_INFO() -ZEND_BEGIN_ARG_INFO(arginfo_bcmod, 0) +ZEND_BEGIN_ARG_INFO_EX(arginfo_bcmod, 0, 0, 2) ZEND_ARG_INFO(0, left_operand) ZEND_ARG_INFO(0, right_operand) + ZEND_ARG_INFO(0, scale) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_bcpowmod, 0, 0, 3) @@ -388,26 +389,38 @@ PHP_FUNCTION(bcdiv) } /* }}} */ -/* {{{ proto string bcmod(string left_operand, string right_operand) +/* {{{ proto string bcmod(string left_operand, string right_operand [, int scale]) Returns the modulus of the two arbitrary precision operands */ PHP_FUNCTION(bcmod) { zend_string *left, *right; + zend_long scale_param = 0; bc_num first, second, result; + int scale = (int)BCG(bc_precision); - ZEND_PARSE_PARAMETERS_START(2, 2) + ZEND_PARSE_PARAMETERS_START(2, 3) Z_PARAM_STR(left) Z_PARAM_STR(right) + Z_PARAM_OPTIONAL + Z_PARAM_LONG(scale_param) ZEND_PARSE_PARAMETERS_END(); + if (ZEND_NUM_ARGS() == 3) { + scale = (int) ((int)scale_param < 0 ? 0 : scale_param); + } + bc_init_num(&first); bc_init_num(&second); bc_init_num(&result); php_str2num(&first, ZSTR_VAL(left)); php_str2num(&second, ZSTR_VAL(right)); - switch (bc_modulo(first, second, &result, 0)) { + switch (bc_modulo(first, second, &result, scale)) { case 0: + if (result->n_scale > scale) { + result = split_bc_num(result); + result->n_scale = scale; + } RETVAL_STR(bc_num2str(result)); break; case -1: diff --git a/ext/bcmath/tests/bcmod.phpt b/ext/bcmath/tests/bcmod.phpt index 5657e02ddc..3e9ab25cb8 100644 --- a/ext/bcmath/tests/bcmod.phpt +++ b/ext/bcmath/tests/bcmod.phpt @@ -9,7 +9,7 @@ bcmath.scale=0 echo bcmod("11", "2"),"\n"; echo bcmod("-1", "5"),"\n"; echo bcmod("8728932001983192837219398127471", "1928372132132819737213"),"\n"; -echo bcmod("3.5", "4"),"\n"; +echo bcmod("3.5", "4", 1),"\n"; echo bcmod("1071", "357.5"),"\n"; ?> --EXPECT-- @@ -17,4 +17,4 @@ echo bcmod("1071", "357.5"),"\n"; -1 1459434331351930289678 3.5 -356.0 +356 diff --git a/ext/bcmath/tests/bcmod_error1.phpt b/ext/bcmath/tests/bcmod_error1.phpt index e36dce285d..68a6dae470 100644 --- a/ext/bcmath/tests/bcmod_error1.phpt +++ b/ext/bcmath/tests/bcmod_error1.phpt @@ -7,7 +7,7 @@ antoni@solucionsinternet.com --FILE-- --EXPECTF-- -Warning: bcmod() expects exactly 2 parameters, 3 given in %s.php on line %d +Warning: bcmod() expects at most 3 parameters, 4 given in %s.php on line %d -- cgit v1.2.1