bigmod multiprecision modular integer arithmetic
bigmod
is a class for doing multiprecision modular
arithmetic over . It supports for example arithmetic
operations, comparisons and exponentiation.
A bigmod
is a pair of two bigints
, where man is called
mantissa
and m modulus
. The modulus is global to all
bigmods
and must be set before a variable of
type bigmod
can be declared. This is done by the following statement:
bigmod::set_modulus(const bigint & m)
Each equivalence class modulo m is represented by its least non-negative
representative, i.e., the mantissa of a bigmod
is chosen in the interval
. At the moment you should not change the
modulus during a computation (see the section ``Initialization'').
Constructors/Destructor
bigmod()
initializes with 0.
bigmod(int)
bigmod(long)
bigmod(unsigned long)
bigmod(double)
bigmod(const bigint &)
bigmod(const bigmod &)
bigmod()
Initialization
static void set_modulus(const bigint & m)
sets the global
modulus to |m|; if m=0 the error_handler will be invoked.
If you call the function set_modulus
after
declaration of variables of type bigmod
, all these variables
might be incorrect, i.e., they might have mantissas which are not in
the proper range. If you want to use bigmod
variables after a
global modulus change, you have to normalize them. This
normalization can be done with the help of the following two
functions:
void a.normalize() normalizes the bigmod
a such that the mantissa of a is in the range ,
where m is the global modulus.
void normalize(bigmod &
a,
const bigmod & b)
sets a to the normalization of b such
that the mantissa of b is in the range , where
m is the global modulus.
Type Checking
Before assigning a bigmod (i.e. the mantissa of a bigmod ) to a machine type (e.g. int ) it is often useful to perform a test which checks if the assignment can be done without overflow. The following functions return 1 if the assignment would be successful, 0 otherwise.
int is_char(const bigmod &)
int is_uchar(const bigmod &)
int is_short(const bigmod &)
int is_ushort(const bigmod &)
int is_int(const bigmod &)
int is_uint(const bigmod &)
int is_long(const bigmod &)
int is_ulong(const bigmod &)
Assignments
The operator = is overloaded. For efficiency reasons, the following functions are also implemented (let a be of type bigmod ):
void a.assign_zero()
a = 0.
void a.assign_one()
a = 1.
void a.assign(int i)
a = i.
void a.assign(long i)
a = i.
void a.assign(unsigned long i)
a = i.
void a.assign(const bigint & b)
a = b.
void a.assign( const bigmod & b)
a = b.
double dbl( const bigmod & a)
returns the mantissa of a as a double approximation.
int a.intify(int & i) const
performs the assignment provided the
assignment can be done without overflow. In that case
the function returns 0
, otherwise it returns 1
and
lets the value of i unchanged.
int a.longify(long & i) const
performs the assignment provided the
assignment can be done without overflow. In that case
the function returns 0
, otherwise it returns 1
and
lets the value of i unchanged.
Access Functions
bigint mantissa( const bigmod & a)
returns the mantissa of the bigmod
a. The mantissa is
chosen in the interval , where m is the
global modulus.
static const bigint modulus() const
returns the value of the global modulus.
Arithmetical Operations
The following operators are overloaded and can be used in exactly the same way as in C:
(unary) -, ++, --
(binary) +, -, *, /
(binary with assignment) +=, -=, *=, /=
The operators / , /= denote ``multiplication with the inverse''. If the inverse does not exist, the error_handler will be invoked. To avoid copying all operators also exist as functions. Let a be of type bigmod .
void add(bigmod & c, const bigmod & a, const bigmod & b)
c = a + b.
void add(bigmod & c, const bigmod & a, long i)
c = a + i.
void add(bigmod & c, long i, const bigmod & b)
c = i + b.
void subtract(bigmod & c, const bigmod & a, const bigmod & b)
c = a - b.
void subtract(bigmod & c, const bigmod & a, long i)
c = a - i.
void subtract(bigmod & c, long i, const bigmod & b)
c = i - b.
void multiply(bigmod & c, const bigmod & a, const bigmod & b)
.
void multiply(bigmod & c, const bigmod & a , long i)
.
void multiply(bigmod & c, long i, const bigmod & b)
.
void divide(bigmod & c, const bigmod & a, const bigmod & b)
, if the inverse of b does not exist,
the error_handler will be invoked.
void divide(bigmod & c, const bigmod & a, long i)
, if the inverse of i does not exist,
the error_handler will be invoked.
void divide(bigmod & c, long i, const bigmod & b)
, if the inverse of b does not exist,
the error_handler will be invoked.
void a.negate()
a = -a.
void negate(bigmod & a, const bigmod & b)
a = -b.
bigint a.invert(int verbose=0)
sets , if the inverse of a exists.
If the inverse does not exist and verbose =0,
the error_handler will be invoked.
If the inverse does not exist and verbose
,
then the function prints a warning and returns
the gcd of a and the global modulus. In this case a remains
unchanged and the program does not exit.
void invert(bigmod & a, const bigmod & b)
sets , if the inverse of b exists.
Otherwise the error_handler will be invoked.
bigmod inverse(const bigmod & a)
returns , if the inverse of a exists. Otherwise
the error_handler will be invoked.
void a.multiply_by_2()
(done by shifting).
void multiply_by_2(bigmod & a, const bigmod & b)
(done by shifting).
void a.divide_by_2()
computes a number such that
, where m is
the global modulus and sets a=b (note: this is not
equivalent to multiplying a with the inverse of 2). The
function prints an error message if the operation is
impossible, i.e., if the mantissa of a is odd and m is
even.
void divide_by_2(bigmod & a, const bigmod & b)
sets a=c with such that
, where m is the global modulus (note:
this is not equivalent to multiplying a with the inverse of 2).
The function prints an error
message if the operation is impossible, i.e., if the mantissa
of b is odd and m is even.
void inc(bigmod & c)
c = c + 1.
void dec(bigmod & c)
c = c - 1.
void square(bigmod & c, const bigmod & a)
.
void power(bigmod & c, const bigmod & a, const bigint & b)
(done with right-to-left binary exponentiation).
void power(bigmod & c, const bigmod & a, long i)
(done with right-to-left binary exponentiation).
Comparisons
bigmod supports the binary operators == , !=
and additionally the unary operator ! (comparison with zero). Let a be an instance of type bigmod .
int a.is_zero() const
returns 1
if a = 0, 0
otherwise.
int a.is_one() const
returns 1
if a = 1, 0
otherwise.
Basic Functions
Let a be of type bigmod .
int a.bit_length() const
returns the bit-length of a's mantissa (see bigint
).
int a.length() const
returns the word-length of a's mantissa (see bigint
).
High-Level Functions
void seed(const bigmod & a)
initializes the Random Number Generator function defined in the kernel with a.
bigmod randomize()
returns a bigmod
with random mantissa in the range
, where m is the global modulus by means of the
Random Number Generator defined in the kernel.
bigmod randomize(const bigmod & a)
returns random bigmod
b with random mantissa in the
range .
Input/Output
Let a be of type bigmod .
The istream
operator >>
and the ostream
operator <<
are
overloaded. Furthermore, you can use the following member functions
for writing to and reading from a file in binary or ASCII
format, respectively. Usually the input and output format of a
bigmod
consist only of its mantissa, since the modulus is global.
Note that the ostream
operator <<
is an exception, it
outputs a bigmod
in the form
where m is the global modulus. Note further
that you have to manage by yourself that successive
bigmod
s have to be separated by blanks.
int x.read_from_file(FILE *fp)
reads x from the binary file using fread.
int x.write_to_file(FILE *fp)
writes x to the binary file using fwrite.
int x.scan_from_file(FILE *fp)
scans x from the ASCII file using fscanf.
int x.print_to_file(FILE *fp)
prints x to the ASCII file using fprintf.
int string_to_bigmod(const char *s, bigmod & a)
converts the string s to a bigmod a and returns the number of
converted characters.
int bigmod_to_string(const bigmod & a, char *s)
converts the bigmod a to a string s and returns the number of
used characters.
bigint
see LiDIA/src/simple_classes/bigmod_appl.c
Volker Müller, Thomas Papanikolaou
Copyright 1995 by the
LiDIA -Group, Universität des Saarlandes