From 9a2af3ca6a9c5de0dfcf8fe8b755bd7be171106c Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 26 Oct 2024 13:54:39 +0100 Subject: [PATCH 1/2] GH-13661: implements gmp_prevprime. Sets the GMP instance to the greatest prime < than the argument provided (or left the instance unmodified). --- ext/gmp/config.m4 | 1 + ext/gmp/gmp.c | 25 +++++++++++++++++++++++++ ext/gmp/gmp.stub.php | 4 ++++ ext/gmp/gmp_arginfo.h | 14 +++++++++++++- ext/gmp/tests/gh13661.phpt | 37 +++++++++++++++++++++++++++++++++++++ 5 files changed, 80 insertions(+), 1 deletion(-) create mode 100644 ext/gmp/tests/gh13661.phpt diff --git a/ext/gmp/config.m4 b/ext/gmp/config.m4 index f0f07d377078d..44c1613492dfb 100644 --- a/ext/gmp/config.m4 +++ b/ext/gmp/config.m4 @@ -41,4 +41,5 @@ if test "$PHP_GMP" != "no"; then PHP_SUBST([GMP_SHARED_LIBADD]) AC_DEFINE([HAVE_GMP], [1], [Define to 1 if the PHP extension 'gmp' is available.]) + AC_CHECK_FUNCS([__gmpz_prevprime]) fi diff --git a/ext/gmp/gmp.c b/ext/gmp/gmp.c index 97172a13a962c..f204c376eecc1 100644 --- a/ext/gmp/gmp.c +++ b/ext/gmp/gmp.c @@ -2080,6 +2080,31 @@ ZEND_FUNCTION(gmp_scan1) } /* }}} */ +#ifdef HAVE___GMPZ_PREVPRIME +ZEND_FUNCTION(gmp_prevprime) +{ + zval *a_arg; + mpz_ptr gmpnum_a, gmpnum_result; + gmp_temp_t temp_a; + + if (zend_parse_parameters(ZEND_NUM_ARGS(), "z", &a_arg) == FAILURE){ + RETURN_THROWS(); + } + + FETCH_GMP_ZVAL(gmpnum_a, a_arg, temp_a, 1); + INIT_GMP_RETVAL(gmpnum_result); + + /* + * If it leads to a prime number the resulting + * GMP instance will reflect the change anyway ; + * on certainty (returning 2) or probability (1). + */ + (void)mpz_prevprime(gmpnum_result, gmpnum_a); + + FREE_GMP_TEMP(temp_a); +} +#endif + ZEND_METHOD(GMP, __construct) { zend_string *arg_str = NULL; diff --git a/ext/gmp/gmp.stub.php b/ext/gmp/gmp.stub.php index 75812c62c5ca3..b63931a00376f 100644 --- a/ext/gmp/gmp.stub.php +++ b/ext/gmp/gmp.stub.php @@ -184,3 +184,7 @@ function gmp_hamdist(GMP|int|string $num1, GMP|int|string $num2): int {} function gmp_nextprime(GMP|int|string $num): GMP {} function gmp_binomial(GMP|int|string $n, int $k): GMP {} + +#ifdef HAVE___GMPZ_PREVPRIME +function gmp_prevprime(GMP|int|string $num): GMP {} +#endif diff --git a/ext/gmp/gmp_arginfo.h b/ext/gmp/gmp_arginfo.h index 31927d3e482bc..570cc237b31f3 100644 --- a/ext/gmp/gmp_arginfo.h +++ b/ext/gmp/gmp_arginfo.h @@ -1,5 +1,5 @@ /* This is a generated file, edit the .stub.php file instead. - * Stub hash: 3aabd5a5d2db0df15b249a425465ae718c13ab6b */ + * Stub hash: 43b8968b67aa77041a10473070778823b7bfc6a9 */ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_gmp_init, 0, 1, GMP, 0) ZEND_ARG_TYPE_MASK(0, num, MAY_BE_LONG|MAY_BE_STRING, NULL) @@ -184,6 +184,12 @@ ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_gmp_binomial, 0, 2, GMP, 0) ZEND_ARG_TYPE_INFO(0, k, IS_LONG, 0) ZEND_END_ARG_INFO() +#if defined(HAVE___GMPZ_PREVPRIME) +ZEND_BEGIN_ARG_WITH_RETURN_OBJ_INFO_EX(arginfo_gmp_prevprime, 0, 1, GMP, 0) + ZEND_ARG_OBJ_TYPE_MASK(0, num, GMP, MAY_BE_LONG|MAY_BE_STRING, NULL) +ZEND_END_ARG_INFO() +#endif + ZEND_BEGIN_ARG_INFO_EX(arginfo_class_GMP___construct, 0, 0, 0) ZEND_ARG_TYPE_MASK(0, num, MAY_BE_LONG|MAY_BE_STRING, "0") ZEND_ARG_TYPE_INFO_WITH_DEFAULT_VALUE(0, base, IS_LONG, 0, "0") @@ -246,6 +252,9 @@ ZEND_FUNCTION(gmp_popcount); ZEND_FUNCTION(gmp_hamdist); ZEND_FUNCTION(gmp_nextprime); ZEND_FUNCTION(gmp_binomial); +#if defined(HAVE___GMPZ_PREVPRIME) +ZEND_FUNCTION(gmp_prevprime); +#endif ZEND_METHOD(GMP, __construct); ZEND_METHOD(GMP, __serialize); ZEND_METHOD(GMP, __unserialize); @@ -302,6 +311,9 @@ static const zend_function_entry ext_functions[] = { ZEND_FE(gmp_hamdist, arginfo_gmp_hamdist) ZEND_FE(gmp_nextprime, arginfo_gmp_nextprime) ZEND_FE(gmp_binomial, arginfo_gmp_binomial) +#if defined(HAVE___GMPZ_PREVPRIME) + ZEND_FE(gmp_prevprime, arginfo_gmp_prevprime) +#endif ZEND_FE_END }; diff --git a/ext/gmp/tests/gh13661.phpt b/ext/gmp/tests/gh13661.phpt new file mode 100644 index 0000000000000..f0530cdee8f08 --- /dev/null +++ b/ext/gmp/tests/gh13661.phpt @@ -0,0 +1,37 @@ +--TEST-- +gmp_prevprime() +--EXTENSIONS-- +gmp +--SKIPIF-- + +--FILE-- + +--EXPECTF-- +object(GMP)#1 (1) { + ["num"]=> + string(1) "0" +} +object(GMP)#1 (1) { + ["num"]=> + string(1) "0" +} +object(GMP)#1 (1) { + ["num"]=> + string(1) "2" +} +object(GMP)#1 (1) { + ["num"]=> + string(1) "2" +} +object(GMP)#1 (1) { + ["num"]=> + string(19) "%d" +} From 3b81dcab9ce623f40306bb0724378d6e7e061ec3 Mon Sep 17 00:00:00 2001 From: David Carlier Date: Sat, 26 Oct 2024 14:20:59 +0100 Subject: [PATCH 2/2] do not bother with objects. --- ext/gmp/tests/gh13661.phpt | 39 ++++++++++++++------------------------ 1 file changed, 14 insertions(+), 25 deletions(-) diff --git a/ext/gmp/tests/gh13661.phpt b/ext/gmp/tests/gh13661.phpt index f0530cdee8f08..546c679bbdf62 100644 --- a/ext/gmp/tests/gh13661.phpt +++ b/ext/gmp/tests/gh13661.phpt @@ -7,31 +7,20 @@ gmp --FILE-- --EXPECTF-- -object(GMP)#1 (1) { - ["num"]=> - string(1) "0" -} -object(GMP)#1 (1) { - ["num"]=> - string(1) "0" -} -object(GMP)#1 (1) { - ["num"]=> - string(1) "2" -} -object(GMP)#1 (1) { - ["num"]=> - string(1) "2" -} -object(GMP)#1 (1) { - ["num"]=> - string(19) "%d" -} +string(1) "0" +string(1) "0" +string(1) "2" +string(1) "2" +string(4) "9973" +string(1) "0" +string(%d) "%d"