X-Git-Url: https://git.distorted.org.uk/~mdw/catacomb/blobdiff_plain/27b1fbee28915abdf10c4dac4a9027583314c623..HEAD:/math/mp.h diff --git a/math/mp.h b/math/mp.h index bb109b53..23e71e36 100644 --- a/math/mp.h +++ b/math/mp.h @@ -37,6 +37,7 @@ #include #include +#include #include #ifndef CATACOMB_MPW_H @@ -196,7 +197,8 @@ extern void mp_destroy(mp */*m*/); extern mp *mp_copy(mp */*m*/); -#define MP_COPY(m) ((m)->ref++, (m)) +#define MP_COPY(m) MUFFLE_WARNINGS_EXPR(GCC_WARNING("-Wunused-value"), \ + ((m)->ref++, (m))) /* --- @mp_drop@ --- * * @@ -890,6 +892,19 @@ extern mp *mp_exp(mp */*d*/, mp */*a*/, mp */*e*/); extern mp *mp_odd(mp */*d*/, mp */*m*/, size_t */*s*/); +/* --- @mp_leastcongruent@ --- * + * + * Arguments: @mp *d@ = pointer to destination + * @mp *b@ = lower bound + * @mp *r@ = representative + * @mp *m@ = modulus + * + * Returns: The smallest integer %$x \equiv r \pmod{m}$% such that + * %$x \ge b$%. + */ + +extern mp *mp_leastcongruent(mp */*d*/, mp */*b*/, mp */*r*/, mp */*m*/); + /*----- More advanced algorithms ------------------------------------------*/ /* --- @mp_sqrt@ --- * @@ -908,6 +923,54 @@ extern mp *mp_odd(mp */*d*/, mp */*m*/, size_t */*s*/); extern mp *mp_sqrt(mp */*d*/, mp */*a*/); +/* --- @mp_nthrt@ --- * + * + * Arguments: @mp *d@ = fake destination + * @mp *a@ = an integer + * @mp *n@ = a strictly positive integer + * @int *exectp_out@ = set nonzero if an exact solution is found + * + * Returns: The integer %$\bigl\lfloor \sqrt[n]{a} \bigr\rfloor$%. + * + * Use: Return an approximation to the %$n$%th root of %$a$%. + * Specifically, it returns the largest integer %$x$% such that + * %$x^n \le a$%. If %$x^n = a$% then @*exactp_out@ is set + * nonzero; otherwise it is set zero. (If @exactp_out@ is null + * then this information is discarded.) + * + * The exponent %$n$% must be strictly positive: it's not clear + * to me what the right answer is for %$n \le 0$%. If %$a$% is + * negative then %$n$% must be odd; otherwise there is no real + * solution. + */ + +extern mp *mp_nthrt(mp */*d*/, mp */*a*/, mp */*n*/, int */*exactp_out*/); + +/* --- @mp_perfect_power_p@ --- * + * + * Arguments: @mp **x@ = where to write the base + * @mp **n@ = where to write the exponent + * @mp *a@ = an integer + * + * Returns: Nonzero if %$a$% is a perfect power. + * + * Use: Returns whether an integer %$a$% is a perfect power, i.e., + * whether it can be written in the form %$a = x^n$% where + * %$|x| > 1$% and %$n > 1$% are integers. If this is possible, + * then (a) store %$x$% and the largest such %$n$% in @*x@ and + * @*n@, and return nonzero; otherwise, store %$x = a$% and + * %$n = 1$% and return zero. (Either @x@ or @n@, or both, may + * be null to discard these outputs.) + * + * Note that %$-1$%, %$0$% and %$1$% are not considered perfect + * powers by this definition. (The exponent is not well-defined + * in these cases, but it seemed better to implement a function + * which worked for all integers.) Note also that %$-4$% is not + * a perfect power since it has no real square root. + */ + +extern int mp_perfect_power_p(mp **/*x*/, mp **/*n*/, mp */*a*/); + /* --- @mp_gcd@ --- * * * Arguments: @mp **gcd, **xx, **yy@ = where to write the results