From 0e1199ac5a1d8410608d488aaa787fb207fc3746 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Mon, 15 Nov 2021 14:23:40 +0000 Subject: [PATCH 1/1] math/mp-sqrt.c, math/pgen-granfrob.c: Publish `squarep' function. It's not super-useful, but it fits thematically with `mp_perfect_power_p', and publishing it is better than not. --- debian/catacomb2.symbols | 1 + math/mp-sqrt.c | 18 ++++++++++++++++++ math/mp.h | 10 ++++++++++ math/pgen-granfrob.c | 14 ++------------ 4 files changed, 31 insertions(+), 12 deletions(-) diff --git a/debian/catacomb2.symbols b/debian/catacomb2.symbols index a8237d89..b03dc296 100644 --- a/debian/catacomb2.symbols +++ b/debian/catacomb2.symbols @@ -308,6 +308,7 @@ libcatacomb.so.2 catacomb2 #MINVER# ## mp-modsqrt mp_modsqrt@Base 2.2.0 + mp_squarep@Base 2.6.99~ ## mp-fibonacci mp_fibonacci@Base 2.1.3 diff --git a/math/mp-sqrt.c b/math/mp-sqrt.c index bf19fe8e..9530ff99 100644 --- a/math/mp-sqrt.c +++ b/math/mp-sqrt.c @@ -126,6 +126,24 @@ mp *mp_sqrt(mp *d, mp *a) return (d); } +/* --- @mp_squarep@ --- * + * + * Arguments: @mp *n@ = an integer + * + * Returns: Nonzero if and only if @n@ is a perfect square, i.e., + * %$n = a^2$% for some rational integer %$a$%. + */ + +int mp_squarep(mp *n) +{ + mp *t = MP_NEW; + int rc; + + if (MP_NEGP(n)) return (0); + t = mp_sqrt(t, n); t = mp_sqr(t, t); + rc = MP_EQ(t, n); mp_drop(t); return (rc); +} + /*----- Test rig ----------------------------------------------------------*/ #ifdef TEST_RIG diff --git a/math/mp.h b/math/mp.h index 23e71e36..75dfd5ba 100644 --- a/math/mp.h +++ b/math/mp.h @@ -923,6 +923,16 @@ extern mp *mp_leastcongruent(mp */*d*/, mp */*b*/, mp */*r*/, mp */*m*/); extern mp *mp_sqrt(mp */*d*/, mp */*a*/); +/* --- @mp_squarep@ --- * + * + * Arguments: @mp *n@ = an integer + * + * Returns: Nonzero if and only if @n@ is a perfect square, i.e., + * %$n = a^2$% for some rational integer %$a$%. + */ + +extern int mp_squarep(mp */*n*/); + /* --- @mp_nthrt@ --- * * * Arguments: @mp *d@ = fake destination diff --git a/math/pgen-granfrob.c b/math/pgen-granfrob.c index 98c8f8cb..05165393 100644 --- a/math/pgen-granfrob.c +++ b/math/pgen-granfrob.c @@ -36,16 +36,6 @@ /*----- Main code ---------------------------------------------------------*/ -static int squarep(mp *n) -{ - mp *t = MP_NEW; - int rc; - - if (MP_NEGP(n)) return (0); - t = mp_sqrt(t, n); t = mp_sqr(t, t); - rc = MP_EQ(t, n); mp_drop(t); return (rc); -} - /* --- @pgen_granfrob@ --- * * * Arguments: @mp *n@ = an integer to test @@ -103,7 +93,7 @@ int pgen_granfrob(mp *n, int a, int b) e = mp_jacobi(&md, n); /* If %$\Delta$% is a perfect square then the test can't work. */ - if (e == 1 && squarep(&md)) { rc = PGEN_ABORT; goto end; } + if (e == 1 && mp_squarep(&md)) { rc = PGEN_ABORT; goto end; } } else { /* Determine parameters. Use Selfridge's `Method A': choose the first * %$\Delta$% from the sequence %$5$%, %$-7$%, %%\dots%%, such that @@ -113,7 +103,7 @@ int pgen_granfrob(mp *n, int a, int b) wa = 1; wd = 5; for (;;) { e = mp_jacobi(&md, n); if (e != +1) break; - if (wd == 25 && squarep(n)) { rc = PGEN_FAIL; goto end; } + if (wd == 25 && mp_squarep(n)) { rc = PGEN_FAIL; goto end; } wd += 2; md.f ^= MP_NEG; } a = 1; d = wd; -- 2.11.0