1156 lines
40 KiB
Plaintext
1156 lines
40 KiB
Plaintext
/*=============================================================================
|
|
|
|
This file is part of FLINT.
|
|
|
|
FLINT is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
FLINT is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with FLINT; if not, write to the Free Software
|
|
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
=============================================================================*/
|
|
/******************************************************************************
|
|
|
|
Copyright (C) 2009 William Hart
|
|
Copyright (C) 2011 Sebastian Pancratz
|
|
|
|
******************************************************************************/
|
|
|
|
*******************************************************************************
|
|
|
|
Memory management
|
|
|
|
*******************************************************************************
|
|
|
|
void fmpz_init(fmpz_t f)
|
|
|
|
A small \code{fmpz_t} is initialised, i.e.\ just a \code{slong}.
|
|
The value is set to zero.
|
|
|
|
void fmpz_init2(fmpz_t f, ulong limbs)
|
|
|
|
Initialises the given \code{fmpz_t} to have space for the given
|
|
number of limbs.
|
|
|
|
If \code{limbs} is zero then a small \code{fmpz_t} is allocated,
|
|
i.e.\ just a \code{slong}. The value is also set to zero. It is
|
|
not necessary to call this function except to save time. A call
|
|
to \code{fmpz_init} will do just fine.
|
|
|
|
void fmpz_clear(fmpz_t f)
|
|
|
|
Clears the given \code{fmpz_t}, releasing any memory associated
|
|
with it, either back to the stack or the OS, depending on
|
|
whether the reentrant or non-reentrant version of FLINT is built.
|
|
|
|
void fmpz_init_set(fmpz_t f, const fmpz_t g)
|
|
|
|
Initialises $f$ and sets it to the value of $g$.
|
|
|
|
void fmpz_init_set_ui(fmpz_t f, ulong g)
|
|
|
|
Initialises $f$ and sets it to the value of $g$.
|
|
|
|
*******************************************************************************
|
|
|
|
Random generation
|
|
|
|
For thread-safety, the randomisation methods take as one of their
|
|
parameters an object of type \code{flint_rand_t}. Before calling
|
|
any of the randomisation functions such an object first has to be
|
|
initialised with a call to \code{flint_randinit()}. When one is
|
|
finished generating random numbers, one should call
|
|
\code{flint_randclear()} to clean up.
|
|
|
|
*******************************************************************************
|
|
|
|
void fmpz_randbits(fmpz_t f, flint_rand_t state, mp_bitcnt_t bits)
|
|
|
|
Generates a random signed integer whose absolute value has the given
|
|
number of bits.
|
|
|
|
void fmpz_randtest(fmpz_t f, flint_rand_t state, mp_bitcnt_t bits)
|
|
|
|
Generates a random signed integer whose absolute value has a number
|
|
of bits which is random from $0$ up to \code{bits} inclusive.
|
|
|
|
void fmpz_randtest_unsigned(fmpz_t f, flint_rand_t state, mp_bitcnt_t bits)
|
|
|
|
Generates a random unsigned integer whose value has a number
|
|
of bits which is random from $0$ up to \code{bits} inclusive.
|
|
|
|
void fmpz_randtest_not_zero(fmpz_t f, flint_rand_t state, mp_bitcnt_t bits)
|
|
|
|
As per \code{fmpz_randtest}, but the result will not be $0$.
|
|
If \code{bits} is set to $0$, an exception will result.
|
|
|
|
void fmpz_randm(fmpz_t f, flint_rand_t state, const fmpz_t m)
|
|
|
|
Generates a random integer in the range $0$ to $m - 1$ inclusive.
|
|
|
|
void fmpz_randtest_mod(fmpz_t f, flint_rand_t state, const fmpz_t m)
|
|
|
|
Generates a random integer in the range $0$ to $m - 1$ inclusive,
|
|
with an increased probability of generating values close to
|
|
the endpoints.
|
|
|
|
void fmpz_randtest_mod_signed(fmpz_t f, flint_rand_t state, const fmpz_t m)
|
|
|
|
Generates a random integer in the range $(-m/2, m/2]$, with an
|
|
increased probability of generating values close to the
|
|
endpoints or close to zero.
|
|
|
|
|
|
*******************************************************************************
|
|
|
|
Conversion
|
|
|
|
*******************************************************************************
|
|
|
|
slong fmpz_get_si(const fmpz_t f)
|
|
|
|
Returns $f$ as a \code{slong}. The result is undefined
|
|
if $f$ does not fit into a \code{slong}.
|
|
|
|
ulong fmpz_get_ui(const fmpz_t f)
|
|
|
|
Returns $f$ as an \code{ulong}. The result is undefined
|
|
if $f$ does not fit into an \code{ulong} or is negative.
|
|
|
|
void fmpz_set_d(fmpz_t f, double c)
|
|
|
|
Sets $f$ to the \code{double} $c$, rounding down towards zero if
|
|
the value of $c$ is fractional. The outcome is undefined if $c$ is
|
|
infinite, not-a-number, or subnormal.
|
|
|
|
double fmpz_get_d(const fmpz_t f)
|
|
|
|
Returns $f$ as a \code{double}, rounding down towards zero if
|
|
\code{f} cannot be represented exactly. The outcome is undefined
|
|
if \code{f} is too large to fit in the normal range of a double.
|
|
|
|
double fmpz_get_d_2exp(slong * exp, const fmpz_t f)
|
|
|
|
Returns $f$ as a normalized \code{double} along with a $2$-exponent
|
|
\code{exp}, i.e.\ if $r$ is the return value then \code{f = r * 2^exp},
|
|
to within 1 ULP.
|
|
|
|
void fmpz_get_mpz(mpz_t x, const fmpz_t f)
|
|
|
|
Sets the \code{mpz_t} $x$ to the same value as $f$.
|
|
|
|
char * fmpz_get_str(char * str, int b, const fmpz_t f)
|
|
|
|
Returns the representation of $f$ in base~$b$, which can vary
|
|
between $2$ and $62$, inclusive.
|
|
|
|
If \code{str} is \code{NULL}, the result string is allocated by
|
|
the function. Otherwise, it is up to the caller to ensure that
|
|
the allocated block of memory is sufficiently large.
|
|
|
|
void fmpz_set_si(fmpz_t f, slong val)
|
|
|
|
Sets $f$ to the given \code{slong} value.
|
|
|
|
void fmpz_set_ui(fmpz_t f, ulong val)
|
|
|
|
Sets $f$ to the given \code{ulong} value.
|
|
|
|
void fmpz_neg_ui(fmpz_t f, ulong val)
|
|
|
|
Sets $f$ to the given \code{ulong} value, and then negates $f$.
|
|
|
|
void fmpz_set_uiui(fmpz_t f, mp_limb_t hi, mp_limb_t lo)
|
|
|
|
Sets $f$ to \code{lo}, plus \code{hi} shifted to the left by
|
|
\code{FLINT_BITS}.
|
|
|
|
void fmpz_neg_uiui(fmpz_t f, mp_limb_t hi, mp_limb_t lo)
|
|
|
|
Sets $f$ to \code{lo}, plus \code{hi} shifted to the left by
|
|
\code{FLINT_BITS}, and then negates $f$.
|
|
|
|
void fmpz_set_mpz(fmpz_t f, const mpz_t x)
|
|
|
|
Sets $f$ to the given \code{mpz_t} value.
|
|
|
|
int fmpz_set_str(fmpz_t f, const char * str, int b)
|
|
|
|
Sets $f$ to the value given in the null-terminated string \code{str},
|
|
in base~$b$. The base~$b$ can vary between $2$ and $62$, inclusive.
|
|
Returns $0$ if the string contains a valid input and $-1$ otherwise.
|
|
|
|
void fmpz_set_ui_smod(fmpz_t f, mp_limb_t x, mp_limb_t m)
|
|
|
|
Sets $f$ to the signed remainder $y \equiv x \bmod m$ satisfying
|
|
$-m/2 < y \leq m/2$, given $x$ which is assumed to satisfy
|
|
$0 \leq x < m$.
|
|
|
|
void flint_mpz_init_set_readonly(mpz_t z, const fmpz_t f)
|
|
|
|
Sets the unitialised \code{mpz_t} $z$ to the value of the
|
|
readonly \code{fmpz_t} $f$.
|
|
|
|
Note that it is assumed that $f$ does not change during
|
|
the lifetime of $z$.
|
|
|
|
The integer $z$ has to be cleared by a call to
|
|
\code{flint_mpz_clear_readonly()}.
|
|
|
|
The suggested use of the two functions is as follows:
|
|
\begin{lstlisting}[language=C]
|
|
fmpz_t f;
|
|
...
|
|
{
|
|
mpz_t z;
|
|
|
|
flint_mpz_init_set_readonly(z, f);
|
|
foo(..., z);
|
|
flint_mpz_clear_readonly(z);
|
|
}
|
|
\end{lstlisting}
|
|
|
|
This provides a convenient function for user code, only
|
|
requiring to work with the types \code{fmpz_t} and \code{mpz_t}.
|
|
|
|
In critical code, the following approach may be favourable:
|
|
\begin{lstlisting}[language=C]
|
|
fmpz_t f;
|
|
...
|
|
{
|
|
__mpz_struct *z;
|
|
|
|
z = _fmpz_promote_val(f);
|
|
foo(..., z);
|
|
_fmpz_demote_val(f);
|
|
}
|
|
\end{lstlisting}
|
|
|
|
void flint_mpz_clear_readonly(mpz_t z)
|
|
|
|
Clears the readonly \code{mpz_t} $z$.
|
|
|
|
void fmpz_init_set_readonly(fmpz_t f, const mpz_t z)
|
|
|
|
Sets the uninitialised \code{fmpz_t} $f$ to a readonly
|
|
version of the integer $z$.
|
|
|
|
Note that the value of $z$ is assumed to remain constant
|
|
throughout the lifetime of $f$.
|
|
|
|
The \code{fmpz_t} $f$ has to be cleared by calling the
|
|
function \code{fmpz_clear_readonly()}.
|
|
|
|
The suggested use of the two functions is as follows:
|
|
\begin{lstlisting}[language=C]
|
|
mpz_t z;
|
|
...
|
|
{
|
|
fmpz_t f;
|
|
|
|
fmpz_init_set_readonly(f, z);
|
|
foo(..., f);
|
|
fmpz_clear_readonly(f);
|
|
}
|
|
\end{lstlisting}
|
|
|
|
void fmpz_clear_readonly(fmpz_t f)
|
|
|
|
Clears the readonly \code{fmpz_t} $f$.
|
|
|
|
*******************************************************************************
|
|
|
|
Input and output
|
|
|
|
*******************************************************************************
|
|
|
|
int fmpz_read(fmpz_t f)
|
|
|
|
Reads a multiprecision integer from \code{stdin}. The format is
|
|
an optional minus sign, followed by one or more digits. The
|
|
first digit should be non-zero unless it is the only digit.
|
|
|
|
In case of success, returns a positive number. In case of failure,
|
|
returns a non-positive number.
|
|
|
|
This convention is adopted in light of the return values of
|
|
\code{scanf} from the standard library and \code{mpz_inp_str}
|
|
from MPIR.
|
|
|
|
int fmpz_fread(FILE * file, fmpz_t f)
|
|
|
|
Reads a multiprecision integer from the stream \code{file}. The
|
|
format is an optional minus sign, followed by one or more digits.
|
|
The first digit should be non-zero unless it is the only digit.
|
|
|
|
In case of success, returns a positive number. In case of failure,
|
|
returns a non-positive number.
|
|
|
|
This convention is adopted in light of the return values of
|
|
\code{scanf} from the standard library and \code{mpz_inp_str}
|
|
from MPIR.
|
|
|
|
size_t fmpz_inp_raw( fmpz_t x, FILE *fin )
|
|
|
|
Reads a multiprecision integer from the stream \code{file}. The
|
|
format is raw binary format write by \code{fmpz_out_raw}.
|
|
|
|
In case of success, return a posivitive number, indicating number of bytes read.
|
|
In case of failure 0.
|
|
|
|
This function calls the \code{mpz_inp_raw} function in library gmp. So that it
|
|
can read the raw data writen by \code{mpz_inp_raw} directly.
|
|
|
|
int fmpz_print(fmpz_t x)
|
|
|
|
Prints the value $x$ to \code{stdout}, without a carriage return(CR).
|
|
The value is printed as either~$0$, the decimal digits of a
|
|
positive integer, or a minus sign followed by the digits of
|
|
a negative integer.
|
|
|
|
In case of success, returns a positive number. In case of failure,
|
|
returns a non-positive number.
|
|
|
|
This convention is adopted in light of the return values of
|
|
\code{flint_printf} from the standard library and \code{mpz_out_str}
|
|
from MPIR.
|
|
|
|
int fmpz_fprint(FILE * file, fmpz_t x)
|
|
|
|
Prints the value $x$ to \code{file}, without a carriage return(CR).
|
|
The value is printed as either~$0$, the decimal digits of a
|
|
positive integer, or a minus sign followed by the digits of
|
|
a negative integer.
|
|
|
|
In case of success, returns a positive number. In case of failure,
|
|
returns a non-positive number.
|
|
|
|
This convention is adopted in light of the return values of
|
|
\code{flint_printf} from the standard library and \code{mpz_out_str}
|
|
from MPIR.
|
|
|
|
size_t fmpz_out_raw( FILE *fout, const fmpz_t x )
|
|
|
|
Writes the value $x$ to \code{file}.
|
|
The value is writen in raw binary format. The integer is written in
|
|
portable format, with 4 bytes of size information, and that many bytes
|
|
of linbs. Both the size and the limbs are written in decreasing
|
|
significance order (i.e., in big-endian).
|
|
|
|
The output can be read with \code{fmpz_inp_raw}.
|
|
|
|
In case of success, return a positive number, indicating number of bytes written.
|
|
In case of failure, return 0.
|
|
|
|
The output of this can also be read by \code{mpz_inp_raw} from GMP >= 2,
|
|
Since this function calls the \code{mpz_inp_raw} function in library gmp.
|
|
|
|
|
|
*******************************************************************************
|
|
|
|
Basic properties and manipulation
|
|
|
|
*******************************************************************************
|
|
|
|
size_t fmpz_sizeinbase(const fmpz_t f, int b)
|
|
|
|
Returns the size of the absolute value of $f$ in base~$b$, measured in
|
|
numbers of digits. The base~$b$ can be between $2$ and $62$, inclusive.
|
|
|
|
mp_bitcnt_t fmpz_bits(const fmpz_t f)
|
|
|
|
Returns the number of bits required to store the absolute
|
|
value of $f$. If $f$ is $0$ then $0$ is returned.
|
|
|
|
mp_size_t fmpz_size(const fmpz_t f)
|
|
|
|
Returns the number of limbs required to store the absolute
|
|
value of $f$. If $f$ is zero then $0$ is returned.
|
|
|
|
int fmpz_sgn(const fmpz_t f)
|
|
|
|
Returns $-1$ if the sign of $f$ is negative, $+1$ if it is positive,
|
|
otherwise returns $0$.
|
|
|
|
mp_bitcnt_t fmpz_val2(const fmpz_t f)
|
|
|
|
Returns the exponent of the largest power of two dividing $f$, or
|
|
equivalently the number of trailing zeros in the binary expansion of $f$.
|
|
If $f$ is zero then $0$ is returned.
|
|
|
|
void fmpz_swap(fmpz_t f, fmpz_t g)
|
|
|
|
Efficiently swaps $f$ and $g$. No data is copied.
|
|
|
|
void fmpz_set(fmpz_t f, const fmpz_t g)
|
|
|
|
Sets $f$ to the same value as $g$.
|
|
|
|
void fmpz_zero(fmpz_t f)
|
|
|
|
Sets $f$ to zero.
|
|
|
|
void fmpz_one(fmpz_t f)
|
|
|
|
Sets $f$ to one.
|
|
|
|
int fmpz_abs_fits_ui(const fmpz_t f)
|
|
|
|
Returns whether the absolute value of $f$
|
|
fits into an \code{ulong}.
|
|
|
|
int fmpz_fits_si(const fmpz_t f)
|
|
|
|
Returns whether the value of $f$ fits into a \code{slong}.
|
|
|
|
void fmpz_setbit(fmpz_t f, ulong i)
|
|
|
|
Sets bit index~$i$ of $f$.
|
|
|
|
int fmpz_tstbit(const fmpz_t f, ulong i)
|
|
|
|
Test bit index~$i$ of $f$ and return $0$ or $1$, accordingly.
|
|
|
|
mp_limb_t fmpz_abs_lbound_ui_2exp(slong * exp, const fmpz_t x, int bits)
|
|
|
|
For nonzero $x$, returns a mantissa $m$ with exactly \code{bits} bits and
|
|
sets \code{exp} to an exponent $e$, such that $|x| \ge m 2^e$. The number
|
|
of bits must be between 1 and \code{FLINT_BITS} inclusive.
|
|
The mantissa is guaranteed to be correctly rounded.
|
|
|
|
mp_limb_t fmpz_abs_ubound_ui_2exp(slong * exp, const fmpz_t x, int bits)
|
|
|
|
For nonzero $x$, returns a mantissa $m$ with exactly \code{bits} bits
|
|
and sets \code{exp} to an exponent $e$, such that $|x| \le m 2^e$.
|
|
The number of bits must be between 1 and \code{FLINT_BITS} inclusive.
|
|
The mantissa is either correctly rounded or one unit too large
|
|
(possibly meaning that the exponent is one too large,
|
|
if the mantissa is a power of two).
|
|
|
|
*******************************************************************************
|
|
|
|
Comparison
|
|
|
|
*******************************************************************************
|
|
|
|
int fmpz_cmp(const fmpz_t f, const fmpz_t g)
|
|
|
|
Returns a negative value if $f < g$, positive value if $g < f$,
|
|
otherwise returns $0$.
|
|
|
|
int fmpz_cmp_ui(const fmpz_t f, ulong g)
|
|
|
|
Returns a negative value if $f < g$, positive value if $g < f$,
|
|
otherwise returns $0$.
|
|
|
|
int fmpz_cmp_si(const fmpz_t f, slong g)
|
|
|
|
Returns a negative value if $f < g$, positive value if $g < f$,
|
|
otherwise returns $0$.
|
|
|
|
int fmpz_cmpabs(const fmpz_t f, const fmpz_t g)
|
|
|
|
Returns a negative value if $\abs{f} < \abs{g}$, positive value if
|
|
$\abs{g} < \abs{f}$, otherwise returns $0$.
|
|
|
|
int fmpz_equal(const fmpz_t f, const fmpz_t g)
|
|
|
|
Returns $1$ if $f$ is equal to $g$, otherwise returns $0$.
|
|
|
|
int fmpz_equal_ui(const fmpz_t f, ulong g)
|
|
|
|
Returns $1$ if $f$ is equal to $g$, otherwise returns $0$.
|
|
|
|
int fmpz_equal_si(const fmpz_t f, slong g)
|
|
|
|
Returns $1$ if $f$ is equal to $g$, otherwise returns $0$.
|
|
|
|
int fmpz_is_zero(const fmpz_t f)
|
|
|
|
Returns $1$ if $f$ is $0$, otherwise returns $0$.
|
|
|
|
int fmpz_is_one(const fmpz_t f)
|
|
|
|
Returns $1$ if $f$ is equal to one, otherwise returns $0$.
|
|
|
|
int fmpz_is_pm1(const fmpz_t f)
|
|
|
|
Returns $1$ if $f$ is equal to one or minus one, otherwise returns
|
|
$0$.
|
|
|
|
int fmpz_is_even(const fmpz_t f)
|
|
|
|
Returns whether the integer $f$ is even.
|
|
|
|
int fmpz_is_odd(const fmpz_t f)
|
|
|
|
Returns whether the integer $f$ is odd.
|
|
|
|
*******************************************************************************
|
|
|
|
Basic arithmetic
|
|
|
|
*******************************************************************************
|
|
|
|
void fmpz_neg(fmpz_t f1, const fmpz_t f2)
|
|
|
|
Sets $f_1$ to $-f_2$.
|
|
|
|
void fmpz_abs(fmpz_t f1, const fmpz_t f2)
|
|
|
|
Sets $f_1$ to the absolute value of $f_2$.
|
|
|
|
void fmpz_add(fmpz_t f, const fmpz_t g, const fmpz_t h)
|
|
|
|
Sets $f$ to $g + h$.
|
|
|
|
void fmpz_add_ui(fmpz_t f, const fmpz_t g, ulong x)
|
|
|
|
Sets $f$ to $g + x$ where $x$ is an \code{ulong}.
|
|
|
|
void fmpz_sub(fmpz_t f, const fmpz_t g, const fmpz_t h)
|
|
|
|
Sets $f$ to $g - h$.
|
|
|
|
void fmpz_sub_ui(fmpz_t f, const fmpz_t g, ulong x)
|
|
|
|
Sets $f$ to $g - x$ where $x$ is an \code{ulong}.
|
|
|
|
void fmpz_mul(fmpz_t f, const fmpz_t g, const fmpz_t h)
|
|
|
|
Sets $f$ to $g \times h$.
|
|
|
|
void fmpz_mul_si(fmpz_t f, const fmpz_t g, slong x)
|
|
|
|
Sets $f$ to $g \times x$ where $x$ is a \code{slong}.
|
|
|
|
void fmpz_mul_ui(fmpz_t f, const fmpz_t g, ulong x)
|
|
|
|
Sets $f$ to $g \times x$ where $x$ is an \code{ulong}.
|
|
|
|
void fmpz_mul2_uiui(fmpz_t f, const fmpz_t g, ulong x, ulong y)
|
|
|
|
Sets $f$ to $g \times x \times y$ where $x$ and $y$ are of type
|
|
\code{ulong}.
|
|
|
|
void fmpz_mul_2exp(fmpz_t f, const fmpz_t g, ulong e)
|
|
|
|
Sets $f$ to $g \times 2^e$.
|
|
|
|
void fmpz_addmul(fmpz_t f, const fmpz_t g, const fmpz_t h)
|
|
|
|
Sets $f$ to $f + g \times h$.
|
|
|
|
void fmpz_addmul_ui(fmpz_t f, const fmpz_t g, ulong x)
|
|
|
|
Sets $f$ to $f + g \times x$ where $x$ is an \code{ulong}.
|
|
|
|
void fmpz_submul(fmpz_t f, const fmpz_t g, const fmpz_t h)
|
|
|
|
Sets $f$ to $f - g \times h$.
|
|
|
|
void fmpz_submul_ui(fmpz_t f, const fmpz_t g, ulong x)
|
|
|
|
Sets $f$ to $f - g \times x$ where $x$ is an \code{ulong}.
|
|
|
|
void fmpz_cdiv_q(fmpz_t f, const fmpz_t g, const fmpz_t h)
|
|
|
|
Sets $f$ to the quotient of $g$ by $h$, rounding up towards
|
|
infinity. If $h$ is $0$ an exception is raised.
|
|
|
|
void fmpz_cdiv_q_si(fmpz_t f, const fmpz_t g, slong h)
|
|
|
|
Sets $f$ to the quotient of $g$ by $h$, rounding up towards
|
|
infinity. If $h$ is $0$ an exception is raised.
|
|
|
|
void fmpz_cdiv_q_ui(fmpz_t f, const fmpz_t g, ulong h)
|
|
|
|
Sets $f$ to the quotient of $g$ by $h$, rounding up towards
|
|
infinity. If $h$ is $0$ an exception is raised.
|
|
|
|
void fmpz_fdiv_q_2exp(fmpz_t f, const fmpz_t g, ulong exp)
|
|
|
|
Sets $f$ to $g$ divided by \code{2^exp}, rounding down
|
|
towards minus infinity.
|
|
|
|
void fmpz_fdiv_q(fmpz_t f, const fmpz_t g, const fmpz_t h)
|
|
|
|
Sets $f$ to the quotient of $g$ by $h$, rounding down towards
|
|
minus infinity. If $h$ is $0$ an exception is raised.
|
|
|
|
void fmpz_fdiv_q_si(fmpz_t f, const fmpz_t g, slong h)
|
|
|
|
Set $f$ to the quotient of $g$ by $h$, rounding down towards
|
|
minus infinity. If $h$ is $0$ an exception is raised.
|
|
|
|
void fmpz_fdiv_q_ui(fmpz_t f, const fmpz_t g, ulong h)
|
|
|
|
Set $f$ to the quotient of $g$ by $h$, rounding down towards
|
|
minus infinity. If $h$ is $0$ an exception is raised.
|
|
|
|
void fmpz_fdiv_qr(fmpz_t f, fmpz_t s, const fmpz_t g, const fmpz_t h)
|
|
|
|
Sets $f$ to the quotient of $g$ by $h$, rounding down towards
|
|
minus infinity and $s$ to the remainder. If $h$ is $0$ an exception
|
|
is raised.
|
|
|
|
void fmpz_fdiv_r(fmpz_t f, const fmpz_t g, const fmpz_t h)
|
|
|
|
Sets $f$ to the remainder from dividing $g$ by $h$ and rounding
|
|
the quotient down towards minus infinity. If $h$ is $0$ an exception
|
|
is raised.
|
|
|
|
void fmpz_fdiv_q_2exp(fmpz_t f, const fmpz_t g, ulong exp)
|
|
|
|
Sets $f$ to $g$ divided by \code{2^exp}, rounding down towards
|
|
minus infinity.
|
|
|
|
void fmpz_fdiv_r_2exp(fmpz_t f, const fmpz_t g, ulong exp)
|
|
|
|
Sets $f$ to the remainder of $g$ upon division by \code{2^exp},
|
|
where the remainder is non-negative.
|
|
|
|
void fmpz_tdiv_q(fmpz_t f, const fmpz_t g, const fmpz_t h)
|
|
|
|
Sets $f$ to the quotient of $g$ by $h$, rounding down towards
|
|
zero. If $h$ is $0$ an exception is raised.
|
|
|
|
void fmpz_tdiv_qr(fmpz_t f, fmpz_t s, const fmpz_t g, const fmpz_t h)
|
|
|
|
Sets $f$ to the quotient of $g$ by $h$, rounding down towards
|
|
zero and $s$ to the remainder. If $h$ is $0$ an exception
|
|
is raised.
|
|
|
|
void fmpz_tdiv_q_si(fmpz_t f, const fmpz_t g, slong h)
|
|
|
|
Set $f$ to the quotient of $g$ by $h$, rounding down towards
|
|
zero. If $h$ is $0$ an exception is raised.
|
|
|
|
void fmpz_tdiv_q_ui(fmpz_t f, const fmpz_t g, ulong h)
|
|
|
|
Set $f$ to the quotient of $g$ by $h$, rounding down towards
|
|
zero. If $h$ is $0$ an exception is raised.
|
|
|
|
ulong fmpz_tdiv_ui(const fmpz_t g, ulong h)
|
|
|
|
Returns the absolute value of the remainder from dividing $g$
|
|
by $h$, rounding towards zero. If $h$ is $0$ an exception is
|
|
raised.
|
|
|
|
void fmpz_tdiv_q_2exp(fmpz_t f, const fmpz_t g, ulong exp)
|
|
|
|
Sets $f$ to $g$ divided by \code{2^exp}, rounding down towards
|
|
zero.
|
|
|
|
void fmpz_divexact(fmpz_t f, const fmpz_t g, const fmpz_t h)
|
|
|
|
Sets $f$ to the quotient of $g$ and $h$, assuming that the
|
|
division is exact, i.e.\ $g$ is a multiple of $h$. If $h$
|
|
is $0$ an exception is raised.
|
|
|
|
void fmpz_divexact_si(fmpz_t f, const fmpz_t g, slong h)
|
|
|
|
Sets $f$ to the quotient of $g$ and $h$, assuming that the
|
|
division is exact, i.e.\ $g$ is a multiple of $h$. If $h$
|
|
is $0$ an exception is raised.
|
|
|
|
void fmpz_divexact_ui(fmpz_t f, const fmpz_t g, ulong h)
|
|
|
|
Sets $f$ to the quotient of $g$ and $h$, assuming that the
|
|
division is exact, i.e.\ $g$ is a multiple of $h$. If $h$
|
|
is $0$ an exception is raised.
|
|
|
|
void fmpz_divexact2_uiui(fmpz_t f, const fmpz_t g, ulong x, ulong y)
|
|
|
|
Sets $f$ to the quotient of $g$ and $h = x \times y$, assuming that
|
|
the division is exact, i.e.\ $g$ is a multiple of $h$.
|
|
If $x$ or $y$ is $0$ an exception is raised.
|
|
|
|
int fmpz_divisible(const fmpz_t f, const fmpz_t g)
|
|
|
|
Returns whether $f$ is divisible by $g > 0$.
|
|
|
|
int fmpz_divisible_si(const fmpz_t f, slong g)
|
|
|
|
Returns whether $f$ is divisible by $g > 0$.
|
|
|
|
void fmpz_mod(fmpz_t f, const fmpz_t g, const fmpz_t h)
|
|
|
|
Sets $f$ to the remainder of $g$ divided by $h$. The remainder
|
|
is always taken to be positive.
|
|
|
|
ulong fmpz_mod_ui(fmpz_t f, const fmpz_t g, ulong x)
|
|
|
|
Sets $f$ to $g$ reduced modulo $x$ where $x$ is an
|
|
\code{ulong}. If $x$ is $0$ an exception will result.
|
|
|
|
ulong fmpz_fdiv_ui(const fmpz_t g, ulong x)
|
|
|
|
Returns the remainder of $g$ modulo $x$ where $x$ is an
|
|
\code{ulong}, without changing $g$. If $x$ is $0$ an
|
|
exception will result.
|
|
|
|
void fmpz_preinvn_init(fmpz_preinvn_t inv, fmpz_t f)
|
|
|
|
Compute a precomputed inverse \code{inv} of \code{f} for use in the
|
|
\code{preinvn} functions listed below.
|
|
|
|
void fmpz_preinvn_clear(fmpz_preinvn_t inv)
|
|
|
|
Clean up the resources used by a precomputed inverse created with the
|
|
\code{fmpz_preinvn_init} function.
|
|
|
|
void fmpz_fdiv_qr_preinvn(fmpz_t f, fmpz_t s, const fmpz_t g,
|
|
const fmpz_t h, const fmpz_preinvn_t hinv)
|
|
|
|
As per \code{fmpz_fdiv_qr}, but takes a precomputed inverse \code{hinv}
|
|
of $h$ constructed using \code{fmpz_preinvn}.
|
|
|
|
This function will be faster than \code{fmpz_fdiv_qr_preinvn} when the
|
|
number of limbs of $h$ is at least \code{PREINVN_CUTOFF}.
|
|
|
|
void fmpz_pow_ui(fmpz_t f, const fmpz_t g, ulong x)
|
|
|
|
Sets $f$ to $g^x$ where $x$ is an \code{ulong}. If
|
|
$x$ is $0$ and $g$ is $0$, then $f$ will be set to $1$.
|
|
|
|
void fmpz_powm_ui(fmpz_t f, const fmpz_t g, ulong e, const fmpz_t m)
|
|
|
|
Sets $f$ to $g^e \bmod{m}$. If $e = 0$, sets $f$ to $1$.
|
|
|
|
Assumes that $m \neq 0$, raises an \code{abort} signal otherwise.
|
|
|
|
void fmpz_powm(fmpz_t f, const fmpz_t g, const fmpz_t e, const fmpz_t m)
|
|
|
|
Sets $f$ to $g^e \bmod{m}$. If $e = 0$, sets $f$ to $1$.
|
|
|
|
Assumes that $m \neq 0$, raises an \code{abort} signal otherwise.
|
|
|
|
slong fmpz_clog(const fmpz_t x, const fmpz_t b)
|
|
|
|
slong fmpz_clog_ui(const fmpz_t x, ulong b)
|
|
|
|
Returns $\ceil{\log_b x}$.
|
|
|
|
Assumes that $x \geq 1$ and $b \geq 2$ and that
|
|
the return value fits into a signed \code{slong}.
|
|
|
|
slong fmpz_flog(const fmpz_t x, const fmpz_t b)
|
|
|
|
slong fmpz_flog_ui(const fmpz_t x, ulong b)
|
|
|
|
Returns $\floor{\log_b x}$.
|
|
|
|
Assumes that $x \geq 1$ and $b \geq 2$ and that
|
|
the return value fits into a signed \code{slong}.
|
|
|
|
double fmpz_dlog(const fmpz_t x)
|
|
|
|
Returns a double precision approximation of the
|
|
natural logarithm of $x$.
|
|
|
|
The accuracy depends on the implementation of the floating-point
|
|
logarithm provided by the C standard library. The result can
|
|
typically be expected to have a relative error no greater than 1-2 bits.
|
|
|
|
int fmpz_sqrtmod(fmpz_t b, const fmpz_t a, const fmpz_t p)
|
|
|
|
Returns whether $a$ is a quadratic residue or zero modulo $p$
|
|
and sets $b$ to a square root of $a$ if this is the case.
|
|
|
|
void fmpz_sqrt(fmpz_t f, const fmpz_t g)
|
|
|
|
Sets $f$ to the integer part of the square root of $g$, where
|
|
$g$ is assumed to be non-negative. If $g$ is negative, an exception
|
|
is raised.
|
|
|
|
void fmpz_sqrtrem(fmpz_t f, fmpz_t r, const fmpz_t g)
|
|
|
|
Sets $f$ to the integer part of the square root of $g$, where $g$ is
|
|
assumed to be non-negative, and sets $r$ to the remainder, that is,
|
|
the difference $g - f^2$. If $g$ is negative, an exception is raised.
|
|
The behaviour is undefined if $f$ and $r$ are aliases.
|
|
|
|
int fmpz_is_square(const fmpz_t f)
|
|
|
|
Returns nonzero if $f$ is a perfect square and zero otherwise.
|
|
|
|
void fmpz_root(fmpz_t r, const fmpz_t f, slong n)
|
|
|
|
Set $r$ to the integer part of the $n$-th root of $f$. Requires that
|
|
$n > 0$ and that if $n$ is even then $f$ be non-negative, otherwise an
|
|
exception is raised.
|
|
|
|
void fmpz_fac_ui(fmpz_t f, ulong n)
|
|
|
|
Sets $f$ to the factorial $n!$ where $n$ is an \code{ulong}.
|
|
|
|
void fmpz_fib_ui(fmpz_t f, ulong n)
|
|
|
|
Sets $f$ to the Fibonacci number $F_n$ where $n$ is an
|
|
\code{ulong}.
|
|
|
|
void fmpz_bin_uiui(fmpz_t f, ulong n, ulong k)
|
|
|
|
Sets $f$ to the binomial coefficient ${n \choose k}$.
|
|
|
|
void fmpz_rfac_ui(fmpz_t r, const fmpz_t x, ulong k)
|
|
|
|
Sets $r$ to the rising factorial $x (x+1) (x+2) \cdots (x+k-1)$.
|
|
|
|
void fmpz_rfac_uiui(fmpz_t r, ulong x, ulong k)
|
|
|
|
Sets $r$ to the rising factorial $x (x+1) (x+2) \cdots (x+k-1)$.
|
|
|
|
void fmpz_mul_tdiv_q_2exp(fmpz_t f, const fmpz_t g, const fmpz_t h, ulong exp)
|
|
|
|
Sets $f$ to the product $g$ and $h$ divided by \code{2^exp}, rounding
|
|
down towards zero.
|
|
|
|
void fmpz_mul_si_tdiv_q_2exp(fmpz_t f, const fmpz_t g, slong x, ulong exp)
|
|
|
|
Sets $f$ to the product $g$ and $x$ divided by \code{2^exp}, rounding
|
|
down towards zero.
|
|
|
|
|
|
*******************************************************************************
|
|
|
|
Greatest common divisor
|
|
|
|
*******************************************************************************
|
|
|
|
void fmpz_gcd(fmpz_t f, const fmpz_t g, const fmpz_t h)
|
|
|
|
Sets $f$ to the greatest common divisor of $g$ and $h$. The
|
|
result is always positive, even if one of $g$ and $h$ is
|
|
negative.
|
|
|
|
void fmpz_lcm(fmpz_t f, const fmpz_t g, const fmpz_t h)
|
|
|
|
Sets $f$ to the least common multiple of $g$ and $h$. The
|
|
result is always nonnegative, even if one of $g$ and $h$ is
|
|
negative.
|
|
|
|
void fmpz_gcdinv(fmpz_t d, fmpz_t a, const fmpz_t f, const fmpz_t g)
|
|
|
|
Given integers $f, g$ with $0 \leq f < g$, computes the
|
|
greatest common divisor $d = \gcd(f, g)$ and the modular
|
|
inverse $a = f^{-1} \pmod{g}$, whenever $f \neq 0$.
|
|
|
|
Assumes that $d$ and $a$ are not aliased.
|
|
|
|
void fmpz_xgcd(fmpz_t d, fmpz_t a, fmpz_t b, const fmpz_t f, const fmpz_t g)
|
|
|
|
Computes the extended GCD of $f$ and $g$, i.e. values $a$ and $b$
|
|
such that $af + bg = d$, where $d = \gcd(f, g)$.
|
|
|
|
Assumes that $d$ is not aliased with $a$ or $b$ and that $a$ and $b$
|
|
are not aliased.
|
|
|
|
void fmpz_xgcd_partial(fmpz_t co2, fmpz_t co1,
|
|
fmpz_t r2, fmpz_t r1, const fmpz_t L)
|
|
|
|
This function is an implementation of Lehmer extended GCD with early
|
|
termination, as used in the \code{qfb} module. It terminates early when
|
|
remainders fall below the specified bound. The initial values \code{r1}
|
|
and \code{r2} are treated as successive remainders in the Euclidean
|
|
algorithm and are replaced with the last two remainders computed. The
|
|
values \code{co1} and \code{co2} are the last two cofactors and satisfy
|
|
the identity \code{co2*r1 - co1*r2 == +/- r2_orig} upon termination, where
|
|
\code{r2_orig} is the starting value of \code{r2} supplied, and \code{r1}
|
|
and \code{r2} are the final values.
|
|
|
|
Aliasing of inputs is not allowed. Similarly aliasing of inputs and outputs
|
|
is not allowed.
|
|
|
|
*******************************************************************************
|
|
|
|
Modular arithmetic
|
|
|
|
*******************************************************************************
|
|
|
|
slong _fmpz_remove(fmpz_t x, const fmpz_t f, double finv)
|
|
|
|
Removes all factors $f$ from $x$ and returns the number of such.
|
|
|
|
Assumes that $x$ is non-zero, that $f > 1$ and that \code{finv}
|
|
is the precomputed \code{double} inverse of $f$ whenever $f$ is
|
|
a small integer and $0$ otherwise.
|
|
|
|
Does not support aliasing.
|
|
|
|
slong fmpz_remove(fmpz_t rop, const fmpz_t op, const fmpz_t f)
|
|
|
|
Remove all occurrences of the factor $f > 1$ from the
|
|
integer \code{op} and sets \code{rop} to the resulting
|
|
integer.
|
|
|
|
If \code{op} is zero, sets \code{rop} to \code{op} and
|
|
returns $0$.
|
|
|
|
Returns an \code{abort} signal if any of the assumptions
|
|
are violated.
|
|
|
|
int fmpz_invmod(fmpz_t f, const fmpz_t g, const fmpz_t h)
|
|
|
|
Sets $f$ to the inverse of $g$ modulo $h$. The value of $h$ may
|
|
not be $0$ otherwise an exception results. If the inverse exists
|
|
the return value will be non-zero, otherwise the return value will
|
|
be $0$ and the value of $f$ undefined.
|
|
|
|
void fmpz_negmod(fmpz_t f, const fmpz_t g, const fmpz_t h)
|
|
|
|
Sets $f$ to $-g \pmod{h}$, assuming $g$ is reduced modulo $h$.
|
|
|
|
int fmpz_jacobi(const fmpz_t a, const fmpz_t p);
|
|
|
|
Computes the Jacobi symbol of $a$ modulo $p$, where $p$ is a prime
|
|
and $a$ is reduced modulo $p$.
|
|
|
|
*******************************************************************************
|
|
|
|
Bit packing and unpacking
|
|
|
|
*******************************************************************************
|
|
|
|
int fmpz_bit_pack(mp_limb_t * arr, mp_bitcnt_t shift,
|
|
mp_bitcnt_t bits, fmpz_t coeff, int negate, int borrow)
|
|
|
|
Shifts the given coefficient to the left by \code{shift} bits and adds
|
|
it to the integer in \code{arr} in a field of the given number of bits.
|
|
|
|
\begin{lstlisting}
|
|
shift bits --------------
|
|
|
|
X X X C C C C 0 0 0 0 0 0 0
|
|
\end{lstlisting}
|
|
|
|
An optional borrow of~$1$ can be subtracted from \code{coeff} before
|
|
it is packed. If \code{coeff} is negative after the borrow, then a
|
|
borrow will be returned by the function.
|
|
|
|
The value of \code{shift} is assumed to be less than \code{FLINT_BITS}.
|
|
All but the first \code{shift} bits of \code{arr} are assumed to be zero
|
|
on entry to the function.
|
|
|
|
The value of \code{coeff} may also be optionally (and notionally) negated
|
|
before it is used, by setting the \code{negate} parameter to $-1$.
|
|
|
|
int fmpz_bit_unpack(fmpz_t coeff, mp_limb_t * arr,
|
|
mp_bitcnt_t shift, mp_bitcnt_t bits, int negate, int borrow)
|
|
|
|
A bit field of the given number of bits is extracted from \code{arr},
|
|
starting after \code{shift} bits, and placed into \code{coeff}. An
|
|
optional borrow of~$1$ may be added to the coefficient. If the result
|
|
is negative, a borrow of $1$ is returned. Finally, the resulting
|
|
\code{coeff} may be negated by setting the \code{negate} parameter to $-1$.
|
|
|
|
The value of \code{shift} is expected to be less than \code{FLINT_BITS}.
|
|
|
|
void fmpz_bit_unpack_unsigned(fmpz_t coeff,
|
|
const mp_limb_t * arr, mp_bitcnt_t shift, mp_bitcnt_t bits)
|
|
|
|
A bit field of the given number of bits is extracted from \code{arr},
|
|
starting after \code{shift} bits, and placed into \code{coeff}.
|
|
|
|
The value of \code{shift} is expected to be less than \code{FLINT_BITS}.
|
|
|
|
*******************************************************************************
|
|
|
|
Logic Operations
|
|
|
|
*******************************************************************************
|
|
|
|
void fmpz_complement(fmpz_t r, const fmpz_t f)
|
|
|
|
The variable \code{r} is set to the ones-complement of \code{f}.
|
|
|
|
void fmpz_clrbit(fmpz_t f, ulong i)
|
|
|
|
Sets the \code{i}th bit in \code{f} to zero.
|
|
|
|
void fmpz_combit(fmpz_t f, ulong i)
|
|
|
|
Complements the \code{i}th bit in \code{f}.
|
|
|
|
void fmpz_and(fmpz_t r, const fmpz_t a, const fmpz_t b)
|
|
|
|
Sets \code{r} to the bit-wise logical \code{and} of \code{a} and \code{b}.
|
|
|
|
void fmpz_or(fmpz_t r, const fmpz_t a, const fmpz_t b)
|
|
|
|
Sets \code{r} to the bit-wise logical (inclusive) \code{or} of
|
|
\code{a} and \code{b}.
|
|
|
|
void fmpz_xor(fmpz_t r, const fmpz_t a, const fmpz_t b)
|
|
|
|
Sets \code{r} to the bit-wise logical exclusive \code{or} of
|
|
\code{a} and \code{b}.
|
|
|
|
int fmpz_popcnt(const fmpz_t a)
|
|
|
|
Returns the number of '1' bits in the given Z (aka Hamming weight or
|
|
population count).
|
|
The return value is undefined if the input is negative.
|
|
|
|
*******************************************************************************
|
|
|
|
Chinese remaindering
|
|
|
|
The following functions can be used to reconstruct an integer from its
|
|
residues modulo a set of small (word-size) prime numbers. The first two
|
|
functions, \code{fmpz_CRT_ui} and \code{fmpz_CRT_ui_unsigned}, are easy
|
|
to use and allow building the result one residue at a time, which is
|
|
useful when the number of needed primes is not known in advance.
|
|
|
|
The remaining functions support performing the modular reductions and
|
|
reconstruction using balanced subdivision. This greatly improves
|
|
efficiency for large integers but assumes that the basis of primes is
|
|
known in advance. The user must precompute a \code{comb}
|
|
structure and temporary working space with \code{fmpz_comb_init} and
|
|
\code{fmpz_comb_temp_init}, and free this data afterwards.
|
|
|
|
For simple demonstration programs showing how to use the CRT functions,
|
|
see \code{crt.c} and \code{multi_crt.c} in the \code{examples}
|
|
directory.
|
|
|
|
*******************************************************************************
|
|
|
|
void fmpz_CRT_ui(fmpz_t out, fmpz_t r1, fmpz_t m1, ulong r2, ulong m2,
|
|
int sign)
|
|
|
|
Uses the Chinese Remainder Theorem to compute the unique integer
|
|
$0 \le x < M$ (if sign = 0) or $-M/2 < x \le M/2$ (if sign = 1)
|
|
congruent to $r_1$ modulo $m_1$ and $r_2$ modulo $m_2$,
|
|
where where $M = m_1 \times m_2$. The result $x$ is stored in \code{out}.
|
|
|
|
It is assumed that $m_1$ and $m_2$ are positive integers greater
|
|
than $1$ and coprime.
|
|
|
|
If sign = 0, it is assumed that $0 \le r_1 < m_1$ and $0 \le r_2 < m_2$.
|
|
Otherwise, it is assumed that $-m_1 \le r_1 < m_1$ and $0 \le r_2 < m_2$.
|
|
|
|
void fmpz_multi_mod_ui(mp_limb_t * out, const fmpz_t in,
|
|
const fmpz_comb_t comb, fmpz_comb_temp_t temp)
|
|
|
|
Reduces the multiprecision integer \code{in} modulo each of the primes
|
|
stored in the \code{comb} structure. The array \code{out} will be filled
|
|
with the residues modulo these primes. The structure \code{temp} is
|
|
temporary space which must be provided by \code{fmpz_comb_temp_init} and
|
|
cleared by \code{fmpz_comb_temp_clear}.
|
|
|
|
void fmpz_multi_CRT_ui_unsigned(fmpz_t output, const mp_limb_t * residues,
|
|
const fmpz_comb_t comb, fmpz_comb_temp_t temp)
|
|
|
|
This function takes a set of residues modulo the list of primes
|
|
contained in the \code{comb} structure and reconstructs the unique
|
|
unsigned multiprecision integer modulo the product of the primes
|
|
which has these residues modulo the corresponding primes. The structure
|
|
\code{temp} is temporary space which must be provided by
|
|
\code{fmpz_comb_temp_init} and cleared by \code{fmpz_comb_temp_clear}.
|
|
|
|
void fmpz_multi_CRT_ui(fmpz_t output, mp_srcptr residues,
|
|
const fmpz_comb_t comb, fmpz_comb_temp_t temp)
|
|
|
|
This function takes a set of residues modulo the list of primes
|
|
contained in the \code{comb} structure and reconstructs a multiprecision
|
|
integer modulo the product of the primes which has
|
|
these residues modulo the corresponding primes.
|
|
|
|
If $N$ is the product of all the primes then \code{out} is normalised to
|
|
be in the range $[0, N)$ if sign = 0 and the range $[-(N-1)/2, N/2]$
|
|
if sign = 1. The array \code{temp} is temporary
|
|
space which must be provided by \code{fmpz_comb_temp_init} and
|
|
cleared by \code{fmpz_comb_temp_clear}.
|
|
|
|
void fmpz_comb_init(fmpz_comb_t comb, mp_srcptr primes, slong num_primes)
|
|
|
|
Initialises a \code{comb} structure for multimodular reduction and
|
|
recombination. The array \code{primes} is assumed to contain
|
|
\code{num_primes} primes each of \code{FLINT_BITS - 1} bits. Modular
|
|
reductions and recombinations will be done modulo this list of primes.
|
|
The \code{primes} array must not be \code{free}'d until the \code{comb}
|
|
structure is no longer required and must be cleared by the user.
|
|
|
|
void fmpz_comb_temp_init(fmpz_comb_temp_t temp, const fmpz_comb_t comb)
|
|
|
|
Creates temporary space to be used by multimodular and CRT functions
|
|
based on an initialised \code{comb} structure.
|
|
|
|
void fmpz_comb_clear(fmpz_comb_t comb)
|
|
|
|
Clears the given \code{comb} structure, releasing any memory it uses.
|
|
|
|
void fmpz_comb_temp_clear(fmpz_comb_temp_t temp)
|
|
|
|
Clears temporary space \code{temp} used by multimodular and CRT functions
|
|
using the given \code{comb} structure.
|
|
|
|
*******************************************************************************
|
|
|
|
Primality testing
|
|
|
|
*******************************************************************************
|
|
|
|
int fmpz_is_probabprime(const fmpz_t p)
|
|
|
|
Performs some trial division and then some probabilistic primality tests.
|
|
If $p$ is definitely composite, the function returns $0$, otherwise it
|
|
is declared probably prime, i.e. prime for most practical purposes, and
|
|
the function returns $1$. The chance of declaring a composite prime is
|
|
very small.
|
|
|
|
Subsequent calls to the same function do not increase the probability of
|
|
the number being prime.
|
|
|
|
int fmpz_is_prime_pseudosquare(const fmpz_t n)
|
|
|
|
Return $0$ is $n$ is composite. If $n$ is too large (greater than about
|
|
$94$ bits) the function fails silently and returns $-1$, otherwise, if
|
|
$n$ is proven prime by the pseudosquares method, return $1$.
|
|
|
|
Tests if $n$ is a prime according to~\citep[Theorem~2.7]{LukPatWil1996}.
|
|
|
|
% "Some results on pseudosquares" by Lukes, Patterson and Williams,
|
|
% Math. Comp. vol 65, No. 213. pp 361-372. See
|
|
% http://www.ams.org/mcom/1996-65-213/S0025-5718-96-00678-3/
|
|
% S0025-5718-96-00678-3.pdf
|
|
|
|
We first factor $N$ using trial division up to some limit $B$.
|
|
In fact, the number of primes used in the trial factoring is at
|
|
most \code{FLINT_PSEUDOSQUARES_CUTOFF}.
|
|
|
|
Next we compute $N/B$ and find the next pseudosquare $L_p$ above
|
|
this value, using a static table as per
|
|
\url{http://research.att.com/~njas/sequences/b002189.txt}.
|
|
|
|
As noted in the text, if $p$ is prime then Step~3 will pass. This
|
|
test rejects many composites, and so by this time we suspect
|
|
that $p$ is prime. If $N$ is $3$ or $7$ modulo $8$, we are done,
|
|
and $N$ is prime.
|
|
|
|
We now run a probable prime test, for which no known
|
|
counterexamples are known, to reject any composites. We then
|
|
proceed to prove $N$ prime by executing Step~4. In the case that
|
|
$N$ is $1$ modulo $8$, if Step~4 fails, we extend the number of primes
|
|
$p_i$ at Step~3 and hope to find one which passes Step~4. We take
|
|
the test one past the largest $p$ for which we have pseudosquares
|
|
$L_p$ tabulated, as this already corresponds to the next $L_p$ which
|
|
is bigger than $2^{64}$ and hence larger than any prime we might be
|
|
testing.
|
|
|
|
As explained in the text, Condition~4 cannot fail if $N$ is prime.
|
|
|
|
The possibility exists that the probable prime test declares a
|
|
composite prime. However in that case an error is printed, as
|
|
that would be of independent interest.
|
|
|