]> granicus.if.org Git - php/commitdiff
Add gmp_kronecker()
authorNikita Popov <nikita.ppv@gmail.com>
Sat, 9 Dec 2017 20:57:41 +0000 (21:57 +0100)
committerNikita Popov <nikita.ppv@gmail.com>
Mon, 11 Dec 2017 18:25:54 +0000 (19:25 +0100)
Exposes the mpz_kronecker(), mpz_si_kronecker() and
mpz_kronecher_si() for computing the Kronecker symbol.

NEWS
UPGRADING
ext/gmp/gmp.c
ext/gmp/php_gmp.h
ext/gmp/tests/gmp_kronecker.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 533f0d451488e3557f0aa56f20d3dc511fe60389..258446fcc53e759f65fae97e4dc6b636e6abe428 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -51,6 +51,7 @@ PHP                                                                        NEWS
   . Added gmp_binomial(n, k). (Nikita)
   . Added gmp_lcm(a, b). (Nikita)
   . Added gmp_perfect_power(a). (Nikita)
+  . Added gmp_kronecker(a, b). (Nikita)
 
 - intl:
   . Fixed bug #75317 (UConverter::setDestinationEncoding changes source instead 
index 955b53ce1c7e0a1b2ade32956a61ffef6143c079..96c5583bec1397239dc5b55f845052d5d16aea20 100644 (file)
--- a/UPGRADING
+++ b/UPGRADING
@@ -89,6 +89,7 @@ GMP:
   . Added gmp_binomial(n, k) for calculating binomial coefficients.
   . Added gmp_lcm(a, b) for calculating the least common multiple.
   . Added gmp_perfect_power(a) to check if number is a perfect power.
+  . Added gmp_kronecker(a, b) to compute the Kronecker symbol.
 
 Intl:
   . Added void Spoofchecker::setRestrictionLevel(int $level) method, available
index 7453b85ba94b0b4ea2ee5705c97aa9535c0d7516..ef9f070f49e6e1adc2b569f7ae8dcde88fb29f1d 100644 (file)
@@ -172,6 +172,7 @@ const zend_function_entry gmp_functions[] = {
        ZEND_FE(gmp_invert,             arginfo_gmp_binary)
        ZEND_FE(gmp_jacobi,             arginfo_gmp_binary)
        ZEND_FE(gmp_legendre,   arginfo_gmp_binary)
+       ZEND_FE(gmp_kronecker,  arginfo_gmp_binary)
        ZEND_FE(gmp_cmp,                arginfo_gmp_binary)
        ZEND_FE(gmp_sign,               arginfo_gmp_unary)
        ZEND_DEP_FE(gmp_random,         arginfo_gmp_random)
@@ -1782,6 +1783,50 @@ ZEND_FUNCTION(gmp_legendre)
 }
 /* }}} */
 
+/* {{{ proto int gmp_kronecker(mixed a, mixed b)
+   Computes the Kronecker symbol */
+ZEND_FUNCTION(gmp_kronecker)
+{
+       zval *a_arg, *b_arg;
+       mpz_ptr gmpnum_a, gmpnum_b;
+       gmp_temp_t temp_a, temp_b;
+       zend_bool use_a_si = 0, use_b_si = 0;
+       int result;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS(), "zz", &a_arg, &b_arg) == FAILURE){
+               return;
+       }
+
+       if (Z_TYPE_P(a_arg) == IS_LONG && Z_TYPE_P(b_arg) != IS_LONG) {
+               use_a_si = 1;
+               temp_a.is_used = 0;
+       } else {
+               FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a);
+       }
+
+       if (Z_TYPE_P(b_arg) == IS_LONG) {
+               use_b_si = 1;
+               temp_b.is_used = 0;
+       } else {
+               FETCH_GMP_ZVAL_DEP(gmpnum_b, b_arg, temp_b, temp_a);
+       }
+
+       if (use_a_si) {
+               ZEND_ASSERT(use_b_si == 0);
+               result = mpz_si_kronecker((gmp_long) Z_LVAL_P(a_arg), gmpnum_b);
+       } else if (use_b_si) {
+               result = mpz_kronecker_si(gmpnum_a, (gmp_long) Z_LVAL_P(b_arg));
+       } else {
+               result = mpz_kronecker(gmpnum_a, gmpnum_b);
+       }
+
+       FREE_GMP_TEMP(temp_a);
+       FREE_GMP_TEMP(temp_b);
+
+       RETURN_LONG(result);
+}
+/* }}} */
+
 /* {{{ proto int gmp_cmp(mixed a, mixed b)
    Compares two numbers */
 ZEND_FUNCTION(gmp_cmp)
index 99dfe476d08c32d99f99c7118760ab1bff208c71..0148e488f54f644450979ee5ad7bac752ce11a75 100644 (file)
@@ -61,6 +61,7 @@ ZEND_FUNCTION(gmp_gcdext);
 ZEND_FUNCTION(gmp_invert);
 ZEND_FUNCTION(gmp_jacobi);
 ZEND_FUNCTION(gmp_legendre);
+ZEND_FUNCTION(gmp_kronecker);
 ZEND_FUNCTION(gmp_cmp);
 ZEND_FUNCTION(gmp_sign);
 ZEND_FUNCTION(gmp_and);
diff --git a/ext/gmp/tests/gmp_kronecker.phpt b/ext/gmp/tests/gmp_kronecker.phpt
new file mode 100644 (file)
index 0000000..8bfa876
--- /dev/null
@@ -0,0 +1,31 @@
+--TEST--
+gmp_kronecker(): Kronecker symbol
+--FILE--
+<?php
+
+var_dump(gmp_kronecker(23, 12));
+var_dump(gmp_kronecker(gmp_init(23), 12));
+var_dump(gmp_kronecker(23, gmp_init(12)));
+var_dump(gmp_kronecker(gmp_init(23), gmp_init(12)));
+var_dump(gmp_kronecker("23", 12));
+var_dump(gmp_kronecker(23, "12"));
+var_dump(gmp_kronecker("23", "12"));
+echo "\n";
+
+var_dump(gmp_kronecker(23, -12));
+var_dump(gmp_kronecker(-23, 12));
+var_dump(gmp_kronecker(-23, -12));
+
+?>
+--EXPECT--
+int(-1)
+int(-1)
+int(-1)
+int(-1)
+int(-1)
+int(-1)
+int(-1)
+
+int(-1)
+int(1)
+int(-1)