Commit:    6d38090c8d1a47844c854a73b57518fb2a7c10a8
Author:    Nikita Popov <ni...@php.net>         Thu, 28 Nov 2013 23:42:23 +0100
Parents:   1c8cbe4b4e8e373b37c740b7d96e4beb96414ea0
Branches:  PHP-5.6 master

Link:       
http://git.php.net/?p=php-src.git;a=commitdiff;h=6d38090c8d1a47844c854a73b57518fb2a7c10a8

Log:
Add gmp_root() and gmp_rootrem() functions

Changed paths:
  M  NEWS
  M  UPGRADING
  M  ext/gmp/gmp.c
  M  ext/gmp/php_gmp.h


Diff:
diff --git a/NEWS b/NEWS
index 29dd740..dabe0cf 100644
--- a/NEWS
+++ b/NEWS
@@ -32,6 +32,8 @@ PHP                                                           
             NEWS
   . Moved GMP to use object as the underlying structure and implemented various
     improvements based on this.
     (RFC: https://wiki.php.net/rfc/operator_overloading_gmp). (Nikita)
+  . Added gmp_root() and gmp_rootrem() functions for calculating nth roots.
+    (Nikita)
 
 - Hash:
   . Added gost-crypto (CryptoPro S-box) GOST hash algo. (Manuel Mausz)
diff --git a/UPGRADING b/UPGRADING
index b680a9f..6392c5f 100755
--- a/UPGRADING
+++ b/UPGRADING
@@ -88,6 +88,9 @@ PHP X.Y UPGRADE NOTES
 5. New Functions
 ========================================
 
+- GMP:
+  Added gmp_root($a, $nth) and gmp_rootrem($a, $nth) for calculating nth roots.
+
 - Openssl:
   Added string openssl_x509_fingerprint($x509, $type, $binary).
 
diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c
index d3b6189..e64acf9 100644
--- a/ext/gmp/gmp.c
+++ b/ext/gmp/gmp.c
@@ -126,6 +126,16 @@ ZEND_BEGIN_ARG_INFO(arginfo_gmp_sqrtrem, 0)
        ZEND_ARG_INFO(0, a)
 ZEND_END_ARG_INFO()
 
+ZEND_BEGIN_ARG_INFO(arginfo_gmp_root, 0)
+       ZEND_ARG_INFO(0, a)
+       ZEND_ARG_INFO(0, nth)
+ZEND_END_ARG_INFO()
+
+ZEND_BEGIN_ARG_INFO(arginfo_gmp_rootrem, 0)
+       ZEND_ARG_INFO(0, a)
+       ZEND_ARG_INFO(0, nth)
+ZEND_END_ARG_INFO()
+
 ZEND_BEGIN_ARG_INFO(arginfo_gmp_perfect_square, 0)
        ZEND_ARG_INFO(0, a)
 ZEND_END_ARG_INFO()
@@ -256,6 +266,8 @@ const zend_function_entry gmp_functions[] = {
        ZEND_FE(gmp_fact,       arginfo_gmp_fact)
        ZEND_FE(gmp_sqrt,       arginfo_gmp_sqrt)
        ZEND_FE(gmp_sqrtrem,    arginfo_gmp_sqrtrem)
+       ZEND_FE(gmp_root,       arginfo_gmp_root)
+       ZEND_FE(gmp_rootrem,    arginfo_gmp_rootrem)
        ZEND_FE(gmp_pow,        arginfo_gmp_pow)
        ZEND_FE(gmp_powm,       arginfo_gmp_powm)
        ZEND_FE(gmp_perfect_square,     arginfo_gmp_perfect_square)
@@ -1514,6 +1526,73 @@ ZEND_FUNCTION(gmp_sqrtrem)
 }
 /* }}} */
 
+/* {{{ proto GMP gmp_root(mixed a, int nth)
+   Takes integer part of nth root */
+ZEND_FUNCTION(gmp_root)
+{
+       zval *a_arg;
+       long nth;
+       mpz_ptr gmpnum_a, gmpnum_result;
+       gmp_temp_t temp_a;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zl", &a_arg, 
&nth) == FAILURE) {
+               return;
+       }
+
+       if (nth <= 0) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "The root must be 
positive");
+               RETURN_FALSE;
+       }
+
+       FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a);
+
+       if (nth % 2 == 0 && mpz_sgn(gmpnum_a) < 0) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't take even 
root of negative number");
+               FREE_GMP_TEMP(temp_a);
+               RETURN_FALSE;
+       }
+
+       INIT_GMP_RETVAL(gmpnum_result);
+       mpz_root(gmpnum_result, gmpnum_a, (unsigned long) nth);
+       FREE_GMP_TEMP(temp_a);
+}
+/* }}} */
+
+/* {{{ proto GMP gmp_rootrem(mixed a, int nth)
+   Calculates integer part of nth root and remainder */
+ZEND_FUNCTION(gmp_rootrem)
+{
+       zval *a_arg;
+       long nth;
+       mpz_ptr gmpnum_a, gmpnum_result1, gmpnum_result2;
+       gmp_temp_t temp_a;
+
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "zl", &a_arg, 
&nth) == FAILURE) {
+               return;
+       }
+
+       if (nth <= 0) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "The root must be 
positive");
+               RETURN_FALSE;
+       }
+
+       FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a);
+
+       if (nth % 2 == 0 && mpz_sgn(gmpnum_a) < 0) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Can't take even 
root of negative number");
+               FREE_GMP_TEMP(temp_a);
+               RETURN_FALSE;
+       }
+
+       array_init(return_value);
+       add_index_zval(return_value, 0, gmp_create(&gmpnum_result1 TSRMLS_CC));
+       add_index_zval(return_value, 1, gmp_create(&gmpnum_result2 TSRMLS_CC));
+
+       mpz_rootrem(gmpnum_result1, gmpnum_result2, gmpnum_a, (unsigned long) 
nth);
+       FREE_GMP_TEMP(temp_a);
+}
+/* }}} */
+
 /* {{{ proto bool gmp_perfect_square(mixed a)
    Checks if a is an exact square */
 ZEND_FUNCTION(gmp_perfect_square)
diff --git a/ext/gmp/php_gmp.h b/ext/gmp/php_gmp.h
index e1aaef8..902c3ac 100644
--- a/ext/gmp/php_gmp.h
+++ b/ext/gmp/php_gmp.h
@@ -45,9 +45,11 @@ ZEND_FUNCTION(gmp_neg);
 ZEND_FUNCTION(gmp_abs);
 ZEND_FUNCTION(gmp_fact);
 ZEND_FUNCTION(gmp_sqrt);
+ZEND_FUNCTION(gmp_sqrtrem);
+ZEND_FUNCTION(gmp_root);
+ZEND_FUNCTION(gmp_rootrem);
 ZEND_FUNCTION(gmp_pow);
 ZEND_FUNCTION(gmp_powm);
-ZEND_FUNCTION(gmp_sqrtrem);
 ZEND_FUNCTION(gmp_perfect_square);
 ZEND_FUNCTION(gmp_prob_prime);
 ZEND_FUNCTION(gmp_gcd);


--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to