Multi-Precision Arithmetic by C++ with no use of assembler
SN library Copyright (C) 1999-2018 K.Tsuru
Reference of class functions part 6
8. SInteger class's member and friend functions
The prototype declarations are given in "sint.h".
This class is derived from "SLong" class by "public".
It is a multi-precision integer class with the radix BRADIX = 32,768. It
is faster than "SLong" class in the program in which many bit
operations are used, e.g. Lucas-Lehmer's test for a large Mersenne's prime
number (see a sample program "smplucas.cpp"). More it is used
in the calculation factorial n!, etc.
For the speed I prepared the functions in which the result is written on
a reference argument, e.g. IIAdd(a, b, r); ---- r=a+b;
But except in a large loop, usual statements such as "r= a+b ;" are allowed to use.
Constructors
form
SInteger(); default constructor
SInteger(double initialValue); initialized by a double value
SInteger(uint v_sz, double initialValue); by size and initial value
SInteger(const SInteger& a); copy constructor
SInteger(const SLong& a); SLong constructor
comment
Last constructor cannot use for the radix conversion. If use, a runtime
error occurs. This is necessary to use the "operator*()" of SLong class. See below.
substitution operators
form
SInteger& operator=(double d);
SInteger& operator=(const SInteger& a);
SInteger& operator=(const SLong& sl);
comment
Last one is also necessary to use the "operator*()" of SLong class and cannot use for the radix conversion.
If an automatic radix conversion is implemented, two "=" statements
1. SL = SI*SI; ----- lhs SL has a type BIN_INT(BRADIX). This is necessary for the "operator*()".
2. SL = SI; -------- It calls the radix conversion.
have different meaning each other.
fundamental operators +, -, *, /, % and compound operators +=, -=, *=,
/=, %=
These operators are overloaded. All the objects which are usable in the
constructors can be used as operands. Inside the function of '+' or '-',
"IIAdd()" or "IISub()" is called. In a large "for" loop, please directly call
faster function "IIAdd()" or "IISub()".
prefix increment and decrement operators ++, --
postfix increment and decrement operators ++, --
These operators are overloaded.
On the overhead
If you get the same result by use of not only "a++;" but also "++a;" it is better to use the latter. Because "a++;" takes time due to making a copy.
bit operators &, |, >>, << and compound operators &=,
|=, >>=, <<=
These operators are overloaded. But operators '~' and '^' are not provided,
because these have no meaning for a multi-precision integer which has variable
bit length.
In the statement of bit shift "a = b>>n;" or "a
= b<<n;" 'n' must be positive integer (unsigned long).
relation operators >, <, ==, !=, >=, <=, ||, &&, !
This class inherits those operators of "SLong" class.
functions for fundamental operations
form
friend void IIAdd(const SInteger& m, const SInteger& n, SInteger& r); r=m+n
friend void IsAdd(const SInteger& m, FType s, SInteger& r); r=m+s
friend void IISub(const SInteger& m, const SInteger& n, SInteger& r); r=m-n
friend void IsSub(const SInteger& m, FType s, SInteger& r); r=m-s
friend void IsMult(const SInteger& m, ulong s, SInteger& r); r=m*s
comment
These functions are provided to avoid the overhead due to making a temporary
copy constructor in "r=m+n;", etc. Usually you can use "r=m+n;".
IIDiv, KnuthIIDiv, NewtonIIDiv
function These functions set quotient and remainder "m/n" in Ldiv_t structure "r". If you do not need the remainder, set "rem = 0".
form
friend void IIDiv(const SInteger& m, const SInteger& n, Ldiv_t& r, int rem);
friend void KnuthIIDiv(const SInteger& m, const SInteger& n, Ldiv_t& r, int rem);
friend void NewtonIIDiv(const SInteger& m, const SInteger& n, Ldiv_t& r, int rem);
comment
"NewtonIIDiv()" provides "SI/SI" by Newton's method in DRADIX, i.e. using SDouble arithmetic which includes the two steps as follows.
1.Radix conversion 'm' and 'n' to SLong.
2.Call NewtonLLdiv().
Due to the overhead of radix conversion it is not so fast. If you want
to use, please directly call this function.
ConvToBin
function "ConvToBin(SL)" returns the expression in the binary radix (SInteger) of 'SL'.
from friend SInteger ConvToBin(const SLong& sl);
ConvToDec
function "m.ConvToDec()" returns the expression in the decimal radix (SLong) of 'm'.
form SLong SInteger::ConvToDec() const;
comment
The following two functions are provided for the radix conversion.
SLong NConvToDec() const; normal method
SLong DConvToDec() const; divide method by use of FFT multiplication.
If "Head()+1 =< iNconvDecMaxFig" "NConvToDec()" is faster than "DConvTodec()". Where "iNconvDecMaxFig" is defined in "sint.h". "ConvToDec()" calls faster function between above. For the algorithm of "DConvToDec()"see the comment of source file "simdcvdc.cpp".
Put, Puts
function "m.Put(s)(...)" makes the radix conversion of 'm' into "SLong" and outputs it.
form
long SInteger::Put(long fig=5, int perLine = 0, int mode = CRLF, int delmt=' ') const;
inline long SInteger::Puts(long fig=5, int perLine = 0, int mode = CRLF, int delmt=' ') const;
comment
The meaning of arguments are the same as those of "SLong" class.