]> granicus.if.org Git - php/commitdiff
Add more GMP functions, fix a couple of bugs
authorStanislav Malyshev <stas@php.net>
Wed, 29 Nov 2000 15:49:18 +0000 (15:49 +0000)
committerStanislav Malyshev <stas@php.net>
Wed, 29 Nov 2000 15:49:18 +0000 (15:49 +0000)
ext/gmp/TODO
ext/gmp/config.m4
ext/gmp/gmp.c
ext/gmp/php_gmp.h

index faa1008577e3d1f76b372fa67279b1bd598ae42d..81098a9cc1b6963663afc30d77f6cafb663d88e9 100644 (file)
@@ -1,9 +1,5 @@
 mpz_mul_2exp
 mpz_[ft]div_[qr]_2exp
-mpz_popcount
-mpz_hamdist
-mpz_scan0
-mpz_scan1
 
 V 3:
 mpz_nextprime
@@ -23,4 +19,4 @@ mpz_urandom[bm]
 mpz_fits_slong_p
 mpz_mul_si
 mpz_odd_p
-mpz_even_p
\ No newline at end of file
+mpz_even_p
index 245c7e35030d2a71a67d0eefdb72c83a70c5ce5f..d7b54e495c0885e9b3f7daf7eb30c864e7d31263 100644 (file)
@@ -5,7 +5,7 @@ dnl If your extension references something external, use with:
 
 PHP_ARG_WITH(gmp, for gmp support,
 dnl Make sure that the comment is aligned:
-[  --with-gmp             Include gmp support])
+[  --with-gmp        Include gmp support])
 
 if test "$PHP_GMP" != "no"; then
 
index a148ff4e24d78a928e781366528e9c7dbd9fd536..f57fa49e85e2111688a20c36753d5a32490d24c4 100644 (file)
@@ -21,9 +21,6 @@
 #include "php_gmp.h"
 #include "ext/standard/info.h"
 
-/* You should tweak config.m4 so this symbol (or some else suitable)
-   gets defined.
-*/
 #if HAVE_GMP
 
 #include <gmp.h>
@@ -36,8 +33,6 @@ static int le_gmp;
 
 static unsigned char first_of_two_force_ref[] = { 2, BYREF_FORCE, BYREF_NONE };
 
-/* Every user visible function must have an entry in gmp_functions[].
-*/
 function_entry gmp_functions[] = {
        ZEND_FE(gmp_init,       NULL)
        ZEND_FE(gmp_intval,     NULL)
@@ -74,6 +69,10 @@ function_entry gmp_functions[] = {
        ZEND_FE(gmp_xor,        NULL)
        ZEND_FE(gmp_setbit,     first_of_two_force_ref)
        ZEND_FE(gmp_clrbit,     first_of_two_force_ref)
+       ZEND_FE(gmp_scan0, NULL)
+       ZEND_FE(gmp_scan1, NULL)
+       ZEND_FE(gmp_popcount, NULL)
+       ZEND_FE(gmp_hamdist, NULL)
        {NULL, NULL, NULL}      /* Must be the last line in gmp_functions[] */
 };
 
@@ -139,7 +138,9 @@ ZEND_MINFO_FUNCTION(gmp)
 if(Z_TYPE_PP(zval) == IS_RESOURCE) { \
        ZEND_FETCH_RESOURCE(gmpnumber, mpz_t *, zval, -1, GMP_RESOURCE_NAME, le_gmp);\
 } else {\
-       convert_to_gmp(&gmpnumber,zval);\
+       if(convert_to_gmp(&gmpnumber,zval) == FAILURE) {\
+               RETURN_FALSE;\
+       }\
        ZEND_REGISTER_RESOURCE(NULL, gmpnumber, le_gmp);\
 }
 
@@ -174,6 +175,7 @@ static int convert_to_gmp(mpz_t * *gmpnumber, zval **val)
                break;
        default:
                zend_error(E_WARNING,"Unable to convert variable to GMP - wrong type");
+               efree(*gmpnumber);
                return FAILURE;
        }
        
@@ -181,9 +183,13 @@ static int convert_to_gmp(mpz_t * *gmpnumber, zval **val)
 }
 
 typedef void (*gmp_unary_op_t)(mpz_ptr, mpz_srcptr);
+typedef int (*gmp_unary_opl_t)(mpz_srcptr);
+
 typedef void (*gmp_unary_ui_op_t)(mpz_ptr, unsigned long);
 
 typedef void (*gmp_binary_op_t)(mpz_ptr, mpz_srcptr, mpz_srcptr);
+typedef int (*gmp_binary_opl_t)(mpz_srcptr, mpz_srcptr);
+
 typedef unsigned long (*gmp_binary_ui_op_t)(mpz_ptr, mpz_srcptr, unsigned long);
 typedef void (*gmp_binary_op2_t)(mpz_ptr, mpz_ptr, mpz_srcptr, mpz_srcptr);
 typedef unsigned long (*gmp_binary_ui_op2_t)(mpz_ptr, mpz_ptr, mpz_srcptr, unsigned long);
@@ -192,9 +198,11 @@ typedef unsigned long (*gmp_binary_ui_op2_t)(mpz_ptr, mpz_ptr, mpz_srcptr, unsig
 
 #define gmp_binary_ui_op(op,uop) _gmp_binary_ui_op(INTERNAL_FUNCTION_PARAM_PASSTHRU, op, uop)
 #define gmp_binary_op(op)         _gmp_binary_ui_op(INTERNAL_FUNCTION_PARAM_PASSTHRU, op, NULL)
+#define gmp_binary_opl(op) _gmp_binary_opl(INTERNAL_FUNCTION_PARAM_PASSTHRU, op)
 
 /* Unary operations */
 #define gmp_unary_op(op)         _gmp_unary_op(INTERNAL_FUNCTION_PARAM_PASSTHRU, op)
+#define gmp_unary_opl(op)         _gmp_unary_opl(INTERNAL_FUNCTION_PARAM_PASSTHRU, op)
 #define gmp_unary_ui_op(op)      _gmp_unary_ui_op(INTERNAL_FUNCTION_PARAM_PASSTHRU, op)
 
 /* 
@@ -333,6 +341,33 @@ static inline void _gmp_unary_op(INTERNAL_FUNCTION_PARAMETERS, gmp_unary_op_t gm
        gmp_zval_unary_op(return_value,a_arg,gmp_op);
 }
 
+static inline void _gmp_unary_opl(INTERNAL_FUNCTION_PARAMETERS, gmp_unary_opl_t gmp_op) {
+       zval **a_arg;
+       mpz_t *gmpnum_a;
+
+       if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &a_arg) == FAILURE){
+               WRONG_PARAM_COUNT;
+       }
+       
+       FETCH_GMP_ZVAL(gmpnum_a, a_arg);
+
+       RETURN_LONG(gmp_op(*gmpnum_a));
+}
+
+static inline void _gmp_binary_opl(INTERNAL_FUNCTION_PARAMETERS, gmp_binary_opl_t gmp_op) {
+       zval **a_arg, **b_arg;
+       mpz_t *gmpnum_a, *gmpnum_b;
+
+       if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &a_arg, &b_arg) == FAILURE){
+               WRONG_PARAM_COUNT;
+       }
+
+       FETCH_GMP_ZVAL(gmpnum_a, a_arg);
+       FETCH_GMP_ZVAL(gmpnum_b, a_arg);
+
+       RETURN_LONG(gmp_op(*gmpnum_a, *gmpnum_b));
+}
+
 
 /* Remove the following function when you have succesfully modified config.m4
    so that your module can be compiled into PHP, it exists only for testing
@@ -844,17 +879,7 @@ ZEND_FUNCTION(gmp_invert)
     */
 ZEND_FUNCTION(gmp_jacobi)
 {
-       zval **a_arg, **b_arg;
-       mpz_t *gmpnum_a, *gmpnum_b;
-
-       if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &a_arg, &b_arg) == FAILURE){
-               WRONG_PARAM_COUNT;
-       }
-
-       FETCH_GMP_ZVAL(gmpnum_a, a_arg);
-       FETCH_GMP_ZVAL(gmpnum_b, a_arg);
-
-       RETURN_LONG(mpz_jacobi(*gmpnum_a, *gmpnum_b));
+       gmp_binary_opl(mpz_jacobi);
 }
 /* }}} */
 
@@ -863,21 +888,12 @@ ZEND_FUNCTION(gmp_jacobi)
     */
 ZEND_FUNCTION(gmp_legendre)
 {
-       zval **a_arg, **b_arg;
-       mpz_t *gmpnum_a, *gmpnum_b;
-
-       if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &a_arg, &b_arg) == FAILURE){
-               WRONG_PARAM_COUNT;
-       }
-
-       FETCH_GMP_ZVAL(gmpnum_a, a_arg);
-       FETCH_GMP_ZVAL(gmpnum_b, a_arg);
-
-       RETURN_LONG(mpz_legendre(*gmpnum_a, *gmpnum_b));
+       gmp_binary_opl(mpz_legendre);
 }
 /* }}} */
 
 /* {{{ proto int gmp_cmp(resource a, resource b)
+   Compare two numbers
     */
 ZEND_FUNCTION(gmp_cmp)
 {
@@ -908,6 +924,7 @@ ZEND_FUNCTION(gmp_cmp)
 /* }}} */
 
 /* {{{ proto int gmp_sign(resource a)
+   Get the sign of the number
     */
 ZEND_FUNCTION(gmp_sign)
 {
@@ -917,7 +934,7 @@ ZEND_FUNCTION(gmp_sign)
        if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &a_arg) == FAILURE){
                WRONG_PARAM_COUNT;
        }
-
+       
        FETCH_GMP_ZVAL(gmpnum_a, a_arg);
 
        RETURN_LONG(mpz_sgn(*gmpnum_a));
@@ -925,6 +942,7 @@ ZEND_FUNCTION(gmp_sign)
 /* }}} */
 
 /* {{{ proto resource gmp_random([int limiter])
+   Get random number
     */
 ZEND_FUNCTION(gmp_random)
 {
@@ -1069,6 +1087,82 @@ ZEND_FUNCTION(gmp_clrbit)
 }
 /* }}} */
 
+/* {{{ proto int gmp_popcount(resource a)
+   Calculate the population count of a
+    */
+ZEND_FUNCTION(gmp_popcount)
+{
+       zval **a_arg;
+       mpz_t *gmpnum_a;
+
+       if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &a_arg) == FAILURE){
+               WRONG_PARAM_COUNT;
+       }
+       
+       FETCH_GMP_ZVAL(gmpnum_a, a_arg);
+
+       RETURN_LONG(mpz_popcount(*gmpnum_a));
+}
+/* }}} */
+
+/* {{{ proto int gmp_hamdist(resource a, resource b)
+   Calculate hamming distance between a and b
+    */
+ZEND_FUNCTION(gmp_hamdist)
+{
+       zval **a_arg, **b_arg;
+       mpz_t *gmpnum_a, *gmpnum_b;
+
+       if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(1, &a_arg, &b_arg) == FAILURE){
+               WRONG_PARAM_COUNT;
+       }
+       
+       FETCH_GMP_ZVAL(gmpnum_a, a_arg);
+       FETCH_GMP_ZVAL(gmpnum_b, b_arg);
+
+       RETURN_LONG(mpz_hamdist(*gmpnum_a, *gmpnum_b));
+}
+/* }}} */
+
+/* {{{ proto int gmp_scan0(resource a, int start)
+   Find first zero bit
+    */
+ZEND_FUNCTION(gmp_scan0)
+{
+       zval **a_arg, **start_arg;
+       mpz_t *gmpnum_a;
+
+       if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &a_arg, &start_arg) == FAILURE){
+               WRONG_PARAM_COUNT;
+       }
+
+       FETCH_GMP_ZVAL(gmpnum_a, a_arg);
+       convert_to_long_ex(start_arg);
+
+       RETURN_LONG(mpz_scan0(*gmpnum_a, Z_LVAL_PP(start_arg)));
+}
+/* }}} */
+
+/* {{{ proto int gmp_scan1(resource a, int start)
+   Find first non-zero bit
+    */
+ZEND_FUNCTION(gmp_scan1)
+{
+       zval **a_arg, **start_arg;
+       mpz_t *gmpnum_a;
+
+       if (ZEND_NUM_ARGS() != 2 || zend_get_parameters_ex(2, &a_arg, &start_arg) == FAILURE){
+               WRONG_PARAM_COUNT;
+       }
+
+       FETCH_GMP_ZVAL(gmpnum_a, a_arg);
+       convert_to_long_ex(start_arg);
+
+       RETURN_LONG(mpz_scan1(*gmpnum_a, Z_LVAL_PP(start_arg)));
+}
+/* }}} */
+
+
 static void _php_gmpnum_free(zend_rsrc_list_entry *rsrc)
 {
        mpz_t *gmpnum = (mpz_t *)rsrc->ptr;
index 519a70757b1049298ef222c3d6c1dfcd90325436..5f8c2350a03ce98560b2842be900ace923241275 100644 (file)
@@ -71,6 +71,10 @@ ZEND_FUNCTION(gmp_xor);
 ZEND_FUNCTION(gmp_random);
 ZEND_FUNCTION(gmp_setbit);
 ZEND_FUNCTION(gmp_clrbit);
+ZEND_FUNCTION(gmp_scan0);
+ZEND_FUNCTION(gmp_scan1);
+ZEND_FUNCTION(gmp_popcount);
+ZEND_FUNCTION(gmp_hamdist);
 
 /* 
        Declare any global variables you may need between the BEGIN