The class BigInt
is intended to represent (signed) integers of
practically unlimited range; it is currently based on the
implementation in the GMP big integer library.
The class MachineInt
is intended to help you write functions which
accept arguments whose type is a machine integer offering a safe interface
for signed and unsigned maching integers.
When the CoCoALib documentation says integer it means both big integers and machine integers which are mainly interchangable. Do remember, though, that operations between two machine integers are handled directly by C++, and problems of overflow can occur.
The few exceptions accepting only long
are clearly indicated and
usually apply to indices and subscripts.
IsEven(n)
-- true iff n
is even
IsOdd(n)
-- true iff n
is odd
IsDivisible(n,d)
-- true iff n
is divisibile by d
IsSquare(n)
-- true iff n
is a perfect square
IsPower(n)
-- true iff n
is a perfect k-th power for some k > 1
IsExactIroot(X,N,r)
-- true iff N
is a perfect r
-th power, assigns iroot(N,r)
to X
Only for BigInt
IsZero(n)
-- true iff n
is zero
IsOne(n)
-- true iff n
is 1
IsMinusOne(n)
-- true iff n
is -1
=
assignment
+
the sum
-
the difference
*
the product
/
integer quotient (truncated "towards zero")
%
remainder, satisfies a = b*(a/b)+(a%b); see also LeastNNegRemainder
and SymmRemainder
==
, !=
<
, <=
, >
, >=
-- comparison (using the normal arithmetic ordering)
-- see also the cmp
function below.
++
, --
(prefix, e.g. ++a
) use these if you can
++
, --
(postfix, e.g. a++
) avoid these if you can, as they create temporaries
(three way comparison)
cmp(a, b)
-- returns an int
which is
< 0
, == 0
, or > 0
if
a < b
, a == b
, or a > b
respectively
CmpAbs(a,b)
-- same as cmp(abs(a),abs(b))
but might be faster.
(Several basic number theoretical operations are defined in NumTheory
)
Let n
be an integer,
let hi
, lo
be machine integers
abs(n)
-- the absolute value of n
sign(n)
-- result is int
:
-1 if n<0
, 0 if n==0
, and +1 if n>0
LeastNNegRemainder(x,m)
-- least non-negative remainder; throws ERR::DivByZero
if m==0
SymmRemainder(x,m)
-- symmetric remainder; throws ERR::DivByZero
if m==0
log(n)
-- natural logarithm of the absolute value of n
(as a double
)
RoundDiv(N,D)
-- rounded division of N
by D
, halves round towards +infinity
isqrt(N)
-- the (truncated) integer part of the square root of N
ILogBase(N,b)
-- the integer part of log(abs(N))/log(b);
error if N=0 or b<2 (as a long
)
These functions return BigInt
power(a, b)
-- returns a
to the power b
(b
must be >=0)
SmallPower(a, b)
-- returns a
to the power b
(b
must be >=0) assuming result fits into a long
factorial(n)
-- factorial for non-negative n
LogFactorial(n)
-- approx natural log of factorial (abs.err. < 5*10^(-8))
RangeFactorial(lo,hi)
-- lo*(lo+1)*(lo+2)*...*hi
binomial(n, r)
-- binomial coefficient
fibonacci(n)
-- n
-th Fibonacci number
iroot(N,r)
-- the (truncated) integer part of the r
-th root of N
(see also IsExactIroot
)
RandomBigInt(lo, hi)
-- a uniform random
integer N
s.t. lo <= N <= hi
(see random
for details).
Only for BigInt
mantissa(n)
-- n represented as a floating-point number.
if n
is zero, produces 0.0
otherwise if n>0
a value between 0.5 and 0.999...
otherwise (when n<0
) a value between -0.5 and -0.999...
The bits of the floating point result are the topmost
bits of the binary representation of n
.
exponent(n)
-- result is a long
whose value is the least integer e such that
2^e > abs(n). If n
is zero, result is zero.
Only for BigInt
NumDigits(n, b)
-- the number of digits (as a long
) n
has
when written in base b
(the result may sometimes to be too large by 1)
Assignment is always to leftmost argument(s) a
, a BigInt
.
Second and/or third argument of type BigInt
.
add(a, b, c)
-- a = b+c
sub(a, b, c)
-- a = b-c
mul(a, b, c)
-- a = b*c
div(a, b, c)
-- a = b/c (truncated integer quotient)
mod(a, b, c)
-- a = b%c (remainder s.t. b = quot*c + rem)
quorem(a, b, c, d)
-- same as a = c/d, b = c%d
divexact(a, b, c)
-- a = b/c (fast, but division must be exact)
power(a, b, c)
-- a = b^c
neg(a, b)
-- a = -b
abs(a, b)
-- a = abs(b)
Error conditions are signalled by exceptions. Examples of error conditions
are impossible arithmetic operations such as division by zero, overly large
arguments (e.g. second argument to binomial must fit into a machine
long
), and exhaustion of resources.
Currently the exception structure is very simplistic:
CoCoA::ErrorInfo
exception; for instance
ERR::ArgTooBig |
value supplied is too large for the answer to be computed |
ERR::BadArg |
unsuitable arg(s) supplied (or input number too large) |
ERR::BadNumBase |
the base must be between 2 and 36 |
ERR::BadPwrZero |
attempt to raise 0 to non-positive power |
ERR::DivByZero |
division by zero |
ERR::ExpTooBig |
exponent is too large |
ERR::IntDivByNeg |
inexact integer division by a negative divisor |
ERR::NegExp |
negative exponent |
ERR::ZeroModulus |
the modulus specified is zero |
The implementation of cmp
is more convoluted than I'd like; it must
avoid internal overflow.
The implementation of RoundDiv
was more difficult than I had expected.
Part of the problem was making sure that needless overflow would never
occur: this was especially relevant in the auxiliary functions
uround_half_up
and uround_half_down
. It would be nice if a
neater implementation could be achieved -- it seems strange that the
C/C++ standard libraries do not already offer such a function. The
standard C functions lround
almost achieves what is needed here, but
there are two significant shortcomings: rounding is always away from zero
(rather than towards +infinity), and there could be loss of accuracy if
the quotient exceeds 1/epsilon. There is also a standard function ldiv
which computes quotient and remainder, but it seems to be faster to compute
the two values explicitly.
The power functions could allow high powers of -1,0,1 (without complaining about the exponent being too big).
Only partial access to all the various division functions offered by the C interface to GMP. Many other GMP functions are not directly accessible.
IsExactIroot
has rather a lot of signatures.
2012
BigInt
and MachineInt
together into IntOperations
-