Skip to content

Commit

Permalink
Scale support for bcmod()
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
cmb69 authored and sgolemon committed Nov 6, 2017
1 parent 5cdf37e commit b152633
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 8 deletions.
21 changes: 17 additions & 4 deletions ext/bcmath/bcmath.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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:
Expand Down
4 changes: 2 additions & 2 deletions ext/bcmath/tests/bcmod.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,12 @@ 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--
1
-1
1459434331351930289678
3.5
356.0
356
4 changes: 2 additions & 2 deletions ext/bcmath/tests/bcmod_error1.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit b152633

Please sign in to comment.