Skip to content

Commit b152633

Browse files
cmb69sgolemon
authored andcommitted
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.
1 parent 5cdf37e commit b152633

File tree

3 files changed

+21
-8
lines changed

3 files changed

+21
-8
lines changed

ext/bcmath/bcmath.c

+17-4
Original file line numberDiff line numberDiff line change
@@ -60,9 +60,10 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_bcdiv, 0, 0, 2)
6060
ZEND_ARG_INFO(0, scale)
6161
ZEND_END_ARG_INFO()
6262

63-
ZEND_BEGIN_ARG_INFO(arginfo_bcmod, 0)
63+
ZEND_BEGIN_ARG_INFO_EX(arginfo_bcmod, 0, 0, 2)
6464
ZEND_ARG_INFO(0, left_operand)
6565
ZEND_ARG_INFO(0, right_operand)
66+
ZEND_ARG_INFO(0, scale)
6667
ZEND_END_ARG_INFO()
6768

6869
ZEND_BEGIN_ARG_INFO_EX(arginfo_bcpowmod, 0, 0, 3)
@@ -388,26 +389,38 @@ PHP_FUNCTION(bcdiv)
388389
}
389390
/* }}} */
390391

391-
/* {{{ proto string bcmod(string left_operand, string right_operand)
392+
/* {{{ proto string bcmod(string left_operand, string right_operand [, int scale])
392393
Returns the modulus of the two arbitrary precision operands */
393394
PHP_FUNCTION(bcmod)
394395
{
395396
zend_string *left, *right;
397+
zend_long scale_param = 0;
396398
bc_num first, second, result;
399+
int scale = (int)BCG(bc_precision);
397400

398-
ZEND_PARSE_PARAMETERS_START(2, 2)
401+
ZEND_PARSE_PARAMETERS_START(2, 3)
399402
Z_PARAM_STR(left)
400403
Z_PARAM_STR(right)
404+
Z_PARAM_OPTIONAL
405+
Z_PARAM_LONG(scale_param)
401406
ZEND_PARSE_PARAMETERS_END();
402407

408+
if (ZEND_NUM_ARGS() == 3) {
409+
scale = (int) ((int)scale_param < 0 ? 0 : scale_param);
410+
}
411+
403412
bc_init_num(&first);
404413
bc_init_num(&second);
405414
bc_init_num(&result);
406415
php_str2num(&first, ZSTR_VAL(left));
407416
php_str2num(&second, ZSTR_VAL(right));
408417

409-
switch (bc_modulo(first, second, &result, 0)) {
418+
switch (bc_modulo(first, second, &result, scale)) {
410419
case 0:
420+
if (result->n_scale > scale) {
421+
result = split_bc_num(result);
422+
result->n_scale = scale;
423+
}
411424
RETVAL_STR(bc_num2str(result));
412425
break;
413426
case -1:

ext/bcmath/tests/bcmod.phpt

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,12 @@ bcmath.scale=0
99
echo bcmod("11", "2"),"\n";
1010
echo bcmod("-1", "5"),"\n";
1111
echo bcmod("8728932001983192837219398127471", "1928372132132819737213"),"\n";
12-
echo bcmod("3.5", "4"),"\n";
12+
echo bcmod("3.5", "4", 1),"\n";
1313
echo bcmod("1071", "357.5"),"\n";
1414
?>
1515
--EXPECT--
1616
1
1717
-1
1818
1459434331351930289678
1919
3.5
20-
356.0
20+
356

ext/bcmath/tests/bcmod_error1.phpt

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ [email protected]
77
<?php if(!extension_loaded("bcmath")) print "skip"; ?>
88
--FILE--
99
<?php
10-
echo bcmod('1', '2', '3');
10+
echo bcmod('1', '2', '3', '4');
1111
?>
1212
--EXPECTF--
13-
Warning: bcmod() expects exactly 2 parameters, 3 given in %s.php on line %d
13+
Warning: bcmod() expects at most 3 parameters, 4 given in %s.php on line %d

0 commit comments

Comments
 (0)