Browse Source

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.
pull/2743/merge
Christoph M. Becker 9 years ago
committed by Sara Golemon
parent
commit
b152633ecb
  1. 21
      ext/bcmath/bcmath.c
  2. 4
      ext/bcmath/tests/bcmod.phpt
  3. 4
      ext/bcmath/tests/bcmod_error1.phpt

21
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:

4
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

4
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
Loading…
Cancel
Save