next up previous contents
Next: bigmod Up: Description of the Previous: Description of the

bigint


bigint multiprecision integer arithmetic


bigint is a class that provides a multiprecision integer arithmetic. A variable of type bigint can hold an integer with arbitrarily many digits. Since all operators which are available for machine integer (e.g. int) are also defined for the type bigint you can regard a variable of type bigint as an int-variable without length restriction.


bigint is an interface that calls functions provided by the kernel. Thus the representation of variables depends on data types used in that level. There is a fixed base B>0, which we call bigint base and which determines the representation of each integer n by the array , with , for and

The coefficients are called base digits , l is called the length

of the representation and the mantissa is the array . We assume that the kernel supports such a vector-based representation for long integers, i.e., it defines such a base B, the functions sign

for the calculation of the sign of a long integer, length for the length of a long integer, and pointers to the mantissas of represented integers.

Constructors/Destructor

bigint()

bigint(int)

bigint(long)

bigint(unsigned long)

bigint(double)

bigint(const bigint &)

bigint()

Type Checking

Before assigning a bigint variable to a machine type variable (e.g. int) it is often useful to perform a test which checks whether the assignment can be done without overflow. The following functions return 1 if an assignment is possible, 0 otherwise.

int is_char(const bigint &)

int is_uchar(const bigint &)

int is_short(const bigint &)

int is_ushort(const bigint &)

int is_int(const bigint &)

int is_uint(const bigint &)

int is_long(const bigint &)

int is_ulong(const bigint &)

Assignments

Let a be of type bigint .

The operator = is overloaded. For efficiency reasons, the following functions are also implemented:

void a.assign_zero()

a = 0.

void a.assign_one()

a = 1.

void a.assign(int i)

a = i.

void a.assign(long ui)

a = ui.

void a.assign(unsigned long ui)

a = ui.

void a.assign(const bigint & I)

a = I.

int a.intify(int & i)

checks whether a can be converted into an int . If this can successfully be done, the function will assign i = a and return 0 ; otherwise, the return value will be 1 and i will be left unchanged.

int a.longify(long & i)

checks whether a can be converted into a long . If this can successfully be done, the function will assign i = a and return 0 ; otherwise, the return value will be 1 and i will be left unchanged.

double dbl(const bigint & a)

returns . If a is too large to be stored in a double variable, x will be the special value infinity which is used in C++ to denote a value too large to be stored in a double variable.

Arithmetical Operations

The following operators are overloaded and can be used in exactly the same way as for machine types in C (e.g. int) :

(unary) -, ++, --
(binary) +, -, *, /, %, <<, >>, , &, |, ^
(binary with assignment) +=, -=, *=, /=, %=, <<=, >>=,
&=, |=

Let a be of type bigint .

To avoid copying, these operations can also be performed by the following functions:

void add(bigint & c, const bigint & a, const bigint & b)

c = a + b.

void add(bigint & c, const bigint & a, long i)

c = a + i.

void add(bigint &c, long i, const bigint & a)

c = i + a.

void subtract(bigint & c, const bigint & a, const bigint & b)

c = a - b.

void subtract(bigint & c, const bigint & a, long i)

c = a - i.

void subtract(bigint & c, long i, const bigint & a)

c = i - a.

void multiply(bigint & c, const bigint & a, const bigint & b)

.

void multiply(bigint & c, const bigint & a, long i)

.

void multiply(bigint & c, long i, const bigint & a)

.

void divide(bigint & c, const bigint & a, const bigint & b)

, if . Otherwise the error_handler will be invoked.

void divide(bigint & c, const bigint & a, long i)

, if . Otherwise the error_handler will be invoked.

void divide(bigint & c, long i, const bigint & a)

, if . Otherwise the error_handler will be invoked.

void remainder(bigint & c, const bigint & a, const bigint & b)

computes c, with , |c| < |b| and .

void remainder(long & c, const bigint & a, long i)

computes c, with , |c| < |i| and .

long remainder(const bigint & a, long i)

returns a value c, with , |c| < |i| and .

long remainder(long & i, const bigint & a)

returns a value c, with , |c| < |a| and .

void div_rem(bigint & q, bigint & r, const bigint & a, const bigint & b)

computes q and r such that , |r| < |b| and .

void div_rem(bigint & q, long & r, const bigint & a, long i)

computes q and r such that , |r| < |i| and .

a.multiply_by_2()

.

a.divide_by_2()

.

void a.negate()

a = -a.

void negate(bigint & b, const bigint & a)

b = -a.

void inc(bigint & c)

c = c + 1.

void dec(bigint & c)

c = c - 1.

void square(bigint & a, const bigint & b)

.

void sqrt(bigint & a, const bigint & b)

a is set to the positive value of , if . Otherwise the error_handler will be invoked.

void power(bigint & c, const bigint & a, const bigint & b)

. For negative exponents b, the result of this computation will be 0, if a > 1, respectively, if and 0, if a=0.

void power(bigint & c, const bigint & a, long i)

. For negative exponents i, the result of this computation will be 0, if a > 1, respectively, if and 0, if a=0.

Shift Operations

void shift_left(bigint & c, const bigint & a, long i)

c = a << i, if . Otherwise the error_handler will be invoked.

void shift_right(bigint & c, const bigint & a, long i)

c = a >> i, if . Otherwise the error_handler will be invoked.

Bit Operations

void and(bigint & c, const bigint & a, const bigint & b)

.

void or(bigint & c, const bigint & a, const bigint & b)

.

void xor(bigint & c, const bigint & a, const bigint & b)

.

void not(bigint & c, const bigint & a)

.

Comparisons

The binary operators == , != , >= , <= , > , < and the unary operator ! (comparison with zero) are overloaded and can be used in exactly the same way as for machine types in C (e.g. int). Let a be an instance of type bigint .

int a.is_zero() const

returns 1 if a = 0, 0 otherwise.

int a.is_one() const

returns 1 if a = 1, 0 otherwise.

int a.is_gt_zero() const

returns 1 if a > 0, 0 otherwise.

int a.is_ge_zero() const

returns 1 if , 0 otherwise.

int a.is_lt_zero() const

returns 1 if a < 0, 0 otherwise.

int a.is_le_zero() const

returns 1 if , 0 otherwise.

int a.is_positive() const

returns 1 if a > 0, 0 otherwise.

int a.is_negative() const

returns 1 if a < 0, 0 otherwise.

int a.is_even() const

returns 1 if , 0 otherwise.

int a.is_odd() const

returns 1 if , 0 otherwise.

int a.abs_compare(const bigint & b) const

returns .

int a.compare(const bigint & b) const

returns .

Basic Functions

Let a be of type bigint .

int a.length() const

returns the number of base digits of the mantissa of a.

int a.bit_length() const

returns the number of bits of the mantissa of a.

int a.bit(unsigned int i) const

returns the i-th bit of a. Bits are numbered from 0 to a.bit_length()-1, where the least significant bit of a has index 0. If a.bit_length(), the function always returns 0.

int a.sign() const

returns -1, 0, 1 if a <, =, > 0, respectively.

unsigned long a.least_significant_digit() const

returns the least significant digit of a, i.e. if the mantissa of a is , the function returns (see basic description).

unsigned long a.most_significant_digit() const

returns the most significant digit of a, i.e. if the mantissa of a is , the function returns (see basic description).

void a.absolute_value()

a = |a|.

bigint abs(const bigint & a)

returns |a|.

void seed(const bigint & a)

initializes the random number generator defined in the kernel with a.

bigint randomize(const bigint & a)

returns a random value r by means of the random number generator defined in the kernel if a>0 and if a<0.

void swap(bigint & a, bigint & b)

exchanges the values of a and b.

High-Level Functions

int fermat(const bigint & a)

performs a probabilistic primality test on a using Fermat's theorem (see [11]). The return value will be 0, if the function recognizes a as composite; otherwise, it will be 1. For any input this function will return 0.

int integer_log(unsigned long x)

returns the position of the most significant bit in an unsigned long. For non-zero x, the return value of this function will be 1 at least; it corresponds to the value .

int is_prime(const bigint & a, int n)

performs a probabilistic primality test on a using the Miller-Rabin method (see [11, page 415,]). If a >1 then the return value 0 implies that a is composite. If a>1 and is_prime returns 1 then a is a prime number with probability .

For any input the return value of is_prime is 0.

int jacobi(const bigint & a, const bigint & b)

returns the value of the Jacobi symbol , hence the Legendre symbol when b is an odd prime (see [11, page 28,]). The Legendre symbol is defined to be 1 if a is a quadratic residue mod b, -1 if a is a quadratic non-residue mod b and 0 if a is a multiple of b.

void nearest(bigint & z, const bigint & u, const bigint & v)

computes an integer z with minimal distance , if . If there are two possible values, the one with the absolutely greater value will be chosen. If v=0 the error_handler will be invoked.

bigint next_prime(const bigint & a)

returns the least integer number > a that satisfies the primality test in function is_prime . For any input this function will return 2.

bigint previous_prime(const bigint & a)

returns the greatest integer number < a that satisfies the primality test in function is_prime . For any input this function will return 0.

void power_mod(bigint & res, const bigint & a, const bigint & n, const bigint & m, int err =0)

calculates in res the least non-negative residue of (, ) using the right-to-left binary exponentiation method (see [11, page 8,]).

For negative exponents n, this function tries to compute the multiplicative inverse of . If it does not exist and err=0, then the error_handler will be invoked. If the multiplicative inverse does not exist and , the gcd of and m will be assigned to res and the function terminates.

long power_test(bigint & b, const bigint & a)

tests, whether a is a perfect power. If a is a k-th power then b is set to k-th root (i.e. ) and k is returned; otherwise the function returns -1.

Greatest Common Divisor

bigint gcd(const bigint & a, const bigint & b)

returns the greatest common divisor (gcd) of a and b as a positive bigint.

bigint bgcd(const bigint & a, const bigint & b)

calculates the gcd of a and b as a positive bigint using a binary method.

bigint dgcd(const bigint & a, const bigint & b)

calculates the gcd of a and b as a positive bigint using Euclidian division and returns its value.

bigint xgcd(bigint & u, bigint & v, const bigint & a, const bigint & b)

returns the gcd of a and b as a positive bigint and computes coefficients u and v with and such that , i.e., uses an extended gcd algorithm.

bigint xgcd_left(bigint & u, const bigint & a, const bigint & b)

returns the gcd of a and b as a positive bigint and computes a coefficient u such that for some integer t .

bigint xgcd_right(bigint & v, const bigint & a, const bigint & b)

returns the gcd of a and b as a positive bigint and computes a coefficient v such that for some integer t .

bigint lcm(const bigint & a, const bigint & b)

returns the least common multiple (lcm) of a and b as a positive bigint.

Input/Output

Let a be of type bigint .

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. The input and output format of a bigint

consist only of the number itself without blanks. Note that you have to manage by yourself that successive bigint s have to be separated by blanks.

void a.read_from_file(FILE * fp)

reads a from the binary file using fread.

void a.write_to_file(FILE * fp)

writes a to binary file using fwrite.

void a.scan_from_file(FILE * fp)

scans a from the ASCII file using fscanf. We assume that the file contains the number in decimal representation.

void a.print_to_file(FILE * fp)

prints a in decimal representation to the ASCII file using fprintf.

The following functions allow conversion between bigint

values and strings:

int string_to_bigint( const char *s, bigint & a)

converts the string s into the bigint a and returns the number of used characters.

int bigint_to_string( const bigint & a, char *s)

converts the bigint a into the string s and returns the number of used characters. The number of characters allocated for string s must be at least .


UNIX manual page mp(3x)


The member functions scan_from_file() , print_to_file() , read_from_file() and write_to_file()

are included because there are still C++ compilers which do not handle fstream s correctly. In a future release, those functions will disappear.


	#include <LiDIA/bigint.h>

	main()
	 {
	     bigint a, b, c;

	     cout << "Please enter a : "; cin >> a ; 
	     cout << "Please enter b : "; cin >> b ;
	     cout << "\n";

	     c = a + b;

	     cout << "a + b = " << c << "\n";
	 }
example:

Please enter a : 123456789123456789
Please enter b : 234567892345678911

a + b = 358024681469135700

For further examples please refer to
LiDIA/src/interfaces/INTERFACE/bigint_appl.c .


Thomas Papanikolaou

Copyright 1995 by the LiDIA -Group, Universität des Saarlandes



next up previous contents
Next: bigmod Up: Description of the Previous: Description of the



LiDIA Administrator
Thu Aug 10 16:41:08 MET DST 1995