]> granicus.if.org Git - php/commitdiff
Scale support for bcmod()
authorChristoph M. Becker <cmbecker69@gmx.de>
Sat, 9 Sep 2017 13:43:02 +0000 (15:43 +0200)
committerSara Golemon <pollita@php.net>
Mon, 6 Nov 2017 22:26:52 +0000 (17:26 -0500)
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
ext/bcmath/tests/bcmod.phpt
ext/bcmath/tests/bcmod_error1.phpt

index e8b87dceff00e72e1cf7b8542d736f7570513ca7..fdabb410666b448d44c20abb24fd18e74fdf8fb7 100644 (file)
@@ -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:
index 5657e02ddc0f03a9506ae0e65da9c1f9e07b7379..3e9ab25cb89154241a555a1f7fdf306538586da9 100644 (file)
@@ -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
index e36dce285db71a7e7d6b5fd2fb62a6e6984c2843..68a6dae470e7b505f453005167767bd7bb34748e 100644 (file)
@@ -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