summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristoph M. Becker <cmbecker69@gmx.de>2017-09-09 15:43:02 +0200
committerSara Golemon <pollita@php.net>2017-11-06 17:26:52 -0500
commitb152633ecb2030e2de1f83d2d42193185ea1bc21 (patch)
tree11ad6377b3c60ca605fdcd4857052613d202b71b
parent5cdf37e6033cf7053132126157747511c2c039f2 (diff)
downloadphp-git-b152633ecb2030e2de1f83d2d42193185ea1bc21.tar.gz
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.
-rw-r--r--ext/bcmath/bcmath.c21
-rw-r--r--ext/bcmath/tests/bcmod.phpt4
-rw-r--r--ext/bcmath/tests/bcmod_error1.phpt4
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
<?php if(!extension_loaded("bcmath")) print "skip"; ?>
--FILE--
<?php
-echo bcmod('1', '2', '3');
+echo bcmod('1', '2', '3', '4');
?>
--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