> is there a possibility to implement bcpowmod() in a
> version prior than PHP5?
>
The following patch can be applied to PHP 4.3.0 or PHP 4.3.1.  It adds
bcpowmod() which isn't scheduled for inclusion until PHP5 and also
includes bugfixes and other modifications slated for the PHP4.3.2 release.

Use of this patch is NOT officially endorsed by the PHP Group and should
be used at your own risk.

That said, it should all work fine :)

((Also attached as a file, but the mailing list tends to munge those))

-Pollita




Index: bcmath.c
===================================================================
RCS file: /repository/php4/ext/bcmath/bcmath.c,v
retrieving revision 1.39.4.2
diff -u -r1.39.4.2 bcmath.c
--- bcmath.c    5 Dec 2002 22:13:58 -0000       1.39.4.2
+++ bcmath.c    23 Feb 2003 00:05:14 -0000
@@ -2,7 +2,7 @@
    +----------------------------------------------------------------------+
    | PHP Version 4                                                        |
    +----------------------------------------------------------------------+
-   | Copyright (c) 1997-2002 The PHP Group                                |
+   | Copyright (c) 1997-2003 The PHP Group                                |
    +----------------------------------------------------------------------+
    | This source file is subject to version 2.02 of the PHP license,      |
    | that is bundled with this package in the file LICENSE, and is        |
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
 */

-/* $Id: bcmath.c,v 1.39.4.2 2002/12/05 22:13:58 helly Exp $ */
+/* $Id: bcmath.c,v 1.39.4.2 2002/12/05 22:13:58 helly Exp $ */

 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -42,6 +42,7 @@
        PHP_FE(bcsqrt,                                                                 
 NULL)
        PHP_FE(bcscale,                                                                
 NULL)
        PHP_FE(bccomp,                                                                 
 NULL)
+       PHP_FE(bcpowmod,                                                               
 NULL)
        {NULL, NULL, NULL}
 };

@@ -110,6 +111,21 @@
        php_info_print_table_end();
 }

+/* {{{ php_str2num
+   Convert to bc_num detecting scale */
+static void php_str2num(bc_num *num, char *str TSRMLS_DC)
+{
+       char *p;
+
+       if (!(p = strchr(str, '.'))) {
+               bc_str2num(num, str, 0 TSRMLS_CC);
+               return;
+       }
+
+       bc_str2num(num, str, strlen(p+1) TSRMLS_CC);
+}
+/* }}} */
+
 /* {{{ proto string bcadd(string left_operand, string right_operand [,
int scale])
    Returns the sum of two arbitrary precision numbers */
 PHP_FUNCTION(bcadd)
@@ -140,9 +156,11 @@
        bc_init_num(&first TSRMLS_CC);
        bc_init_num(&second TSRMLS_CC);
        bc_init_num(&result TSRMLS_CC);
-       bc_str2num(&first, Z_STRVAL_PP(left), scale TSRMLS_CC);
-       bc_str2num(&second, Z_STRVAL_PP(right), scale TSRMLS_CC);
+       php_str2num(&first, Z_STRVAL_PP(left) TSRMLS_CC);
+       php_str2num(&second, Z_STRVAL_PP(right) TSRMLS_CC);
        bc_add (first, second, &result, scale);
+       if (result->n_scale > scale)
+               result->n_scale = scale;
        Z_STRVAL_P(return_value) = bc_num2str(result);
        Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
        Z_TYPE_P(return_value) = IS_STRING;
@@ -183,9 +201,11 @@
        bc_init_num(&first TSRMLS_CC);
        bc_init_num(&second TSRMLS_CC);
        bc_init_num(&result TSRMLS_CC);
-       bc_str2num(&first, Z_STRVAL_PP(left), scale TSRMLS_CC);
-       bc_str2num(&second, Z_STRVAL_PP(right), scale TSRMLS_CC);
+       php_str2num(&first, Z_STRVAL_PP(left) TSRMLS_CC);
+       php_str2num(&second, Z_STRVAL_PP(right) TSRMLS_CC);
        bc_sub (first, second, &result, scale);
+       if (result->n_scale > scale)
+               result->n_scale = scale;
        Z_STRVAL_P(return_value) = bc_num2str(result);
        Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
        Z_TYPE_P(return_value) = IS_STRING;
@@ -226,9 +246,11 @@
        bc_init_num(&first TSRMLS_CC);
        bc_init_num(&second TSRMLS_CC);
        bc_init_num(&result TSRMLS_CC);
-       bc_str2num(&first, Z_STRVAL_PP(left), scale TSRMLS_CC);
-       bc_str2num(&second, Z_STRVAL_PP(right), scale TSRMLS_CC);
+       php_str2num(&first, Z_STRVAL_PP(left) TSRMLS_CC);
+       php_str2num(&second, Z_STRVAL_PP(right) TSRMLS_CC);
        bc_multiply (first, second, &result, scale TSRMLS_CC);
+       if (result->n_scale > scale)
+               result->n_scale = scale;
        Z_STRVAL_P(return_value) = bc_num2str(result);
        Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
        Z_TYPE_P(return_value) = IS_STRING;
@@ -269,10 +291,12 @@
        bc_init_num(&first TSRMLS_CC);
        bc_init_num(&second TSRMLS_CC);
        bc_init_num(&result TSRMLS_CC);
-       bc_str2num(&first, Z_STRVAL_PP(left), scale TSRMLS_CC);
-       bc_str2num(&second, Z_STRVAL_PP(right), scale TSRMLS_CC);
+       php_str2num(&first, Z_STRVAL_PP(left) TSRMLS_CC);
+       php_str2num(&second, Z_STRVAL_PP(right) TSRMLS_CC);
        switch (bc_divide (first, second, &result, scale TSRMLS_CC)) {
                case 0: /* OK */
+                       if (result->n_scale > scale)
+                               result->n_scale = scale;
                        Z_STRVAL_P(return_value) = bc_num2str(result);
                        Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
                        Z_TYPE_P(return_value) = IS_STRING;
@@ -329,6 +353,40 @@
 }
 /* }}} */

+/* {{{ proto string bcpowmod(string x, string y, string mod [, int scale])
+   Returns the value of an arbitrary precision number raised to the power
of another reduced by a modulous */
+PHP_FUNCTION(bcpowmod)
+{
+       char *left, *right, *modulous;
+       int left_len, right_len, modulous_len;
+       bc_num first, second, mod, result;
+       int scale=bc_precision;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|l", &left,
&left_len, &right, &right_len, &modulous, &modulous_len, &scale) ==
FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       bc_init_num(&first TSRMLS_CC);
+       bc_init_num(&second TSRMLS_CC);
+       bc_init_num(&mod TSRMLS_CC);
+       bc_init_num(&result TSRMLS_CC);
+       php_str2num(&first, left TSRMLS_CC);
+       php_str2num(&second, right TSRMLS_CC);
+       php_str2num(&mod, modulous TSRMLS_CC);
+       bc_raisemod(first, second, mod, &result, scale TSRMLS_CC);
+       if (result->n_scale > scale)
+       result->n_scale = scale;
+       Z_STRVAL_P(return_value) = bc_num2str(result);
+       Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
+       Z_TYPE_P(return_value) = IS_STRING;
+       bc_free_num(&first);
+       bc_free_num(&second);
+       bc_free_num(&mod);
+       bc_free_num(&result);
+       return;
+}
+/* }}} */
+
 /* {{{ proto string bcpow(string x, string y [, int scale])
    Returns the value of an arbitrary precision number raised to the power
of another */
 PHP_FUNCTION(bcpow)
@@ -359,9 +417,11 @@
        bc_init_num(&first TSRMLS_CC);
        bc_init_num(&second TSRMLS_CC);
        bc_init_num(&result TSRMLS_CC);
-       bc_str2num(&first, Z_STRVAL_PP(left), scale TSRMLS_CC);
-       bc_str2num(&second, Z_STRVAL_PP(right), scale TSRMLS_CC);
+       php_str2num(&first, Z_STRVAL_PP(left) TSRMLS_CC);
+       php_str2num(&second, Z_STRVAL_PP(right) TSRMLS_CC);
        bc_raise (first, second, &result, scale TSRMLS_CC);
+       if (result->n_scale > scale)
+               result->n_scale = scale;
        Z_STRVAL_P(return_value) = bc_num2str(result);
        Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
        Z_TYPE_P(return_value) = IS_STRING;
@@ -399,8 +459,10 @@
        }
        convert_to_string_ex(left);
        bc_init_num(&result TSRMLS_CC);
-       bc_str2num(&result, Z_STRVAL_PP(left), scale TSRMLS_CC);
+       php_str2num(&result, Z_STRVAL_PP(left) TSRMLS_CC);
        if (bc_sqrt (&result, scale TSRMLS_CC) != 0) {
+               if (result->n_scale > scale)
+                       result->n_scale = scale;
                Z_STRVAL_P(return_value) = bc_num2str(result);
                Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
                Z_TYPE_P(return_value) = IS_STRING;
Index: php_bcmath.h
===================================================================
RCS file: /repository/php4/ext/bcmath/php_bcmath.h,v
retrieving revision 1.11.4.1
diff -u -r1.11.4.1 php_bcmath.h
--- php_bcmath.h        22 Nov 2002 09:27:08 -0000      1.11.4.1
+++ php_bcmath.h        23 Feb 2003 00:05:14 -0000
@@ -2,7 +2,7 @@
    +----------------------------------------------------------------------+
    | PHP Version 4                                                        |
    +----------------------------------------------------------------------+
-   | Copyright (c) 1997-2002 The PHP Group                                |
+   | Copyright (c) 1997-2003 The PHP Group                                |
    +----------------------------------------------------------------------+
    | This source file is subject to version 2.02 of the PHP license,      |
    | that is bundled with this package in the file LICENSE, and is        |
@@ -60,6 +60,7 @@
 PHP_FUNCTION(bcsqrt);
 PHP_FUNCTION(bccomp);
 PHP_FUNCTION(bcscale);
+PHP_FUNCTION(bcpowmod);

 #else



Index: bcmath.c
===================================================================
RCS file: /repository/php4/ext/bcmath/bcmath.c,v
retrieving revision 1.39.4.2
diff -u -r1.39.4.2 bcmath.c
--- bcmath.c    5 Dec 2002 22:13:58 -0000       1.39.4.2
+++ bcmath.c    23 Feb 2003 00:05:14 -0000
@@ -2,7 +2,7 @@
    +----------------------------------------------------------------------+
    | PHP Version 4                                                        |
    +----------------------------------------------------------------------+
-   | Copyright (c) 1997-2002 The PHP Group                                |
+   | Copyright (c) 1997-2003 The PHP Group                                |
    +----------------------------------------------------------------------+
    | This source file is subject to version 2.02 of the PHP license,      |
    | that is bundled with this package in the file LICENSE, and is        |
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: bcmath.c,v 1.39.4.2 2002/12/05 22:13:58 helly Exp $ */
+/* $Id: bcmath.c,v 1.39.4.2 2002/12/05 22:13:58 helly Exp $ */ 
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
@@ -42,6 +42,7 @@
        PHP_FE(bcsqrt,                                                                 
 NULL)
        PHP_FE(bcscale,                                                                
 NULL)
        PHP_FE(bccomp,                                                                 
 NULL)
+       PHP_FE(bcpowmod,                                                               
 NULL)
        {NULL, NULL, NULL}
 };
 
@@ -110,6 +111,21 @@
        php_info_print_table_end();
 }
 
+/* {{{ php_str2num
+   Convert to bc_num detecting scale */
+static void php_str2num(bc_num *num, char *str TSRMLS_DC) 
+{
+       char *p;
+
+       if (!(p = strchr(str, '.'))) {
+               bc_str2num(num, str, 0 TSRMLS_CC);
+               return;
+       }
+
+       bc_str2num(num, str, strlen(p+1) TSRMLS_CC);
+}
+/* }}} */
+
 /* {{{ proto string bcadd(string left_operand, string right_operand [, int scale])
    Returns the sum of two arbitrary precision numbers */
 PHP_FUNCTION(bcadd)
@@ -140,9 +156,11 @@
        bc_init_num(&first TSRMLS_CC);
        bc_init_num(&second TSRMLS_CC);
        bc_init_num(&result TSRMLS_CC);
-       bc_str2num(&first, Z_STRVAL_PP(left), scale TSRMLS_CC);
-       bc_str2num(&second, Z_STRVAL_PP(right), scale TSRMLS_CC);
+       php_str2num(&first, Z_STRVAL_PP(left) TSRMLS_CC);
+       php_str2num(&second, Z_STRVAL_PP(right) TSRMLS_CC);
        bc_add (first, second, &result, scale);
+       if (result->n_scale > scale)
+               result->n_scale = scale;
        Z_STRVAL_P(return_value) = bc_num2str(result);
        Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
        Z_TYPE_P(return_value) = IS_STRING;
@@ -183,9 +201,11 @@
        bc_init_num(&first TSRMLS_CC);
        bc_init_num(&second TSRMLS_CC);
        bc_init_num(&result TSRMLS_CC);
-       bc_str2num(&first, Z_STRVAL_PP(left), scale TSRMLS_CC);
-       bc_str2num(&second, Z_STRVAL_PP(right), scale TSRMLS_CC);
+       php_str2num(&first, Z_STRVAL_PP(left) TSRMLS_CC);
+       php_str2num(&second, Z_STRVAL_PP(right) TSRMLS_CC);
        bc_sub (first, second, &result, scale);
+       if (result->n_scale > scale)
+               result->n_scale = scale;
        Z_STRVAL_P(return_value) = bc_num2str(result);
        Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
        Z_TYPE_P(return_value) = IS_STRING;
@@ -226,9 +246,11 @@
        bc_init_num(&first TSRMLS_CC);
        bc_init_num(&second TSRMLS_CC);
        bc_init_num(&result TSRMLS_CC);
-       bc_str2num(&first, Z_STRVAL_PP(left), scale TSRMLS_CC);
-       bc_str2num(&second, Z_STRVAL_PP(right), scale TSRMLS_CC);
+       php_str2num(&first, Z_STRVAL_PP(left) TSRMLS_CC);
+       php_str2num(&second, Z_STRVAL_PP(right) TSRMLS_CC);
        bc_multiply (first, second, &result, scale TSRMLS_CC);
+       if (result->n_scale > scale)
+               result->n_scale = scale;
        Z_STRVAL_P(return_value) = bc_num2str(result);
        Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
        Z_TYPE_P(return_value) = IS_STRING;
@@ -269,10 +291,12 @@
        bc_init_num(&first TSRMLS_CC);
        bc_init_num(&second TSRMLS_CC);
        bc_init_num(&result TSRMLS_CC);
-       bc_str2num(&first, Z_STRVAL_PP(left), scale TSRMLS_CC);
-       bc_str2num(&second, Z_STRVAL_PP(right), scale TSRMLS_CC);
+       php_str2num(&first, Z_STRVAL_PP(left) TSRMLS_CC);
+       php_str2num(&second, Z_STRVAL_PP(right) TSRMLS_CC);
        switch (bc_divide (first, second, &result, scale TSRMLS_CC)) {
                case 0: /* OK */
+                       if (result->n_scale > scale)
+                               result->n_scale = scale;
                        Z_STRVAL_P(return_value) = bc_num2str(result);
                        Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
                        Z_TYPE_P(return_value) = IS_STRING;
@@ -329,6 +353,40 @@
 }
 /* }}} */
 
+/* {{{ proto string bcpowmod(string x, string y, string mod [, int scale])
+   Returns the value of an arbitrary precision number raised to the power of another 
reduced by a modulous */
+PHP_FUNCTION(bcpowmod)
+{
+       char *left, *right, *modulous;
+       int left_len, right_len, modulous_len;
+       bc_num first, second, mod, result;
+       int scale=bc_precision;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "sss|l", &left, 
&left_len, &right, &right_len, &modulous, &modulous_len, &scale) == FAILURE) {
+               WRONG_PARAM_COUNT;
+       }
+
+       bc_init_num(&first TSRMLS_CC);
+       bc_init_num(&second TSRMLS_CC);
+       bc_init_num(&mod TSRMLS_CC);
+       bc_init_num(&result TSRMLS_CC);
+       php_str2num(&first, left TSRMLS_CC);
+       php_str2num(&second, right TSRMLS_CC);
+       php_str2num(&mod, modulous TSRMLS_CC);
+       bc_raisemod(first, second, mod, &result, scale TSRMLS_CC);
+       if (result->n_scale > scale)
+       result->n_scale = scale;
+       Z_STRVAL_P(return_value) = bc_num2str(result);
+       Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
+       Z_TYPE_P(return_value) = IS_STRING;
+       bc_free_num(&first);
+       bc_free_num(&second);
+       bc_free_num(&mod);
+       bc_free_num(&result);
+       return;
+}
+/* }}} */
+
 /* {{{ proto string bcpow(string x, string y [, int scale])
    Returns the value of an arbitrary precision number raised to the power of another 
*/
 PHP_FUNCTION(bcpow)
@@ -359,9 +417,11 @@
        bc_init_num(&first TSRMLS_CC);
        bc_init_num(&second TSRMLS_CC);
        bc_init_num(&result TSRMLS_CC);
-       bc_str2num(&first, Z_STRVAL_PP(left), scale TSRMLS_CC);
-       bc_str2num(&second, Z_STRVAL_PP(right), scale TSRMLS_CC);
+       php_str2num(&first, Z_STRVAL_PP(left) TSRMLS_CC);
+       php_str2num(&second, Z_STRVAL_PP(right) TSRMLS_CC);
        bc_raise (first, second, &result, scale TSRMLS_CC);
+       if (result->n_scale > scale)
+               result->n_scale = scale;
        Z_STRVAL_P(return_value) = bc_num2str(result);
        Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
        Z_TYPE_P(return_value) = IS_STRING;
@@ -399,8 +459,10 @@
        }
        convert_to_string_ex(left);
        bc_init_num(&result TSRMLS_CC);
-       bc_str2num(&result, Z_STRVAL_PP(left), scale TSRMLS_CC);
+       php_str2num(&result, Z_STRVAL_PP(left) TSRMLS_CC);
        if (bc_sqrt (&result, scale TSRMLS_CC) != 0) {
+               if (result->n_scale > scale)
+                       result->n_scale = scale;
                Z_STRVAL_P(return_value) = bc_num2str(result);
                Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
                Z_TYPE_P(return_value) = IS_STRING;
Index: php_bcmath.h
===================================================================
RCS file: /repository/php4/ext/bcmath/php_bcmath.h,v
retrieving revision 1.11.4.1
diff -u -r1.11.4.1 php_bcmath.h
--- php_bcmath.h        22 Nov 2002 09:27:08 -0000      1.11.4.1
+++ php_bcmath.h        23 Feb 2003 00:05:14 -0000
@@ -2,7 +2,7 @@
    +----------------------------------------------------------------------+
    | PHP Version 4                                                        |
    +----------------------------------------------------------------------+
-   | Copyright (c) 1997-2002 The PHP Group                                |
+   | Copyright (c) 1997-2003 The PHP Group                                |
    +----------------------------------------------------------------------+
    | This source file is subject to version 2.02 of the PHP license,      |
    | that is bundled with this package in the file LICENSE, and is        |
@@ -60,6 +60,7 @@
 PHP_FUNCTION(bcsqrt);
 PHP_FUNCTION(bccomp);
 PHP_FUNCTION(bcscale);
+PHP_FUNCTION(bcpowmod);
 
 #else
 

-- 
PHP Development Mailing List <http://www.php.net/>
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to