Multi-Precision Arithmetic by C++ with no
use of assembler
SN library Copyright (C) 1999-2018 K.Tsuru
Reference of class functions
part 3
Sorry I did not make a list in alphabetical order.
Below I shall use symbols "SD" for a "SDouble" variable,
"SL" a "SLong" one, etc.
5. SLong class's member and friend functions
The prototype declarations are given in "slong.h". This is a multi-precision integer class with the radix DRADIX = 10,000.
Almost functions below can be called by derived "SInteger" class object, but a few
cannot. They are commented as "(SLong only)".
Constructors
form
SLong(); default constructor
SLong(double d); set a value by "double"
SLong(const char* s); set a value by a literal (SLong only)
SLong(NumberType tp, uint v_sz);
SLong(NumberType tp, uint v_sz, double initialValue);
SLong(const SLong& a) copy constructor
About fourth constructor It can specify the type and size. Give 'tp' 'INTEGER=1'(SLong) or
'BIN_INT=5'(SInteger). When the necessary size is previously known, it is better
to use this constructor.
When "v_sz > minArraySize" it takes into the irreducible size mode.
When "v_sz = 0" it does not allocate the memory of
"figure[]".
When "v_sz > 0" it initializes by zero.
Fifth constructor can specify an initial value by "double".
Warning
Constructor "SLong(const SDouble& sd);" is not given because of the reason
written in "slong.h". Please use a substitution operator such as
SDouble SD;
SLong SL. // SLong SL(SD); causes an error.
.....
SL = SD;
substitution operators
form
SLong& SLong:: operator=(const char *s); (SLong only)
SLong& SLong:: operator=(double m);
SLong& SLong:: operator=(const SDouble& sd);
SLong& SLong:: operator=(const Ldiv_t& a);
comment These are overloaded. About "Ldiv_t" see below. Second operator can be used
as ones for "long", "int", etc.
fundamental operators +, -, *, /, % and compound operators +=, -=, *=, /=,
%=
These operators are overloaded. All the objects which are usable in the constructors
can be used as operands.
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
they 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 >, <, ==, !=, >=, <=, ||, &&, !
These operators are overloaded by inline functions in the file "sninline.h".
A statement "if(x)" cannot be used then please use "if(x.Sign())". If you want to know
the relation between multi-precision object and zero, a statement "if(x>0.0)" call a
temporary constructor for "0.0", then it is better to use ""if(x.Sign()>0)".
LLcompare
function "LLCompare(m, n);" compares the absolute value of
'm' with that of 'n',
and returns
1 if |m|>|n|,
0 if |m|==|n|,
-1 if |m|<|n|.
form friend int LLCompare(const SLong& m, const SLong& n);
LsMult
function "LsMult(SL, n) returns "SL*n".
form friend SLong LsMult(const SLong& m, ulong n);
comment A statement "r=m*n;" gives the same result but the
temporally constructor "SLong temp(n);" is called. Then in a large "for"
loop it is better to use this function to avoid overhead. It is the same as "LsDiv()", "DsMult()" and
"DsDiv()".
LsDiv
function "LsDiv(SL, n) returns "SL/n".
form friend SLong LsDiv(const SLong& m, ulong n, long* rem = NULL);
comment If "rem != NULL" it sets remainder into "*rem". It returns
"m/n" for "0<n<=ULONG_MAX/radix".
enumerating constants
function It gives the definition of values for switching division routine.
form enum SLong::{ Knuth = 0, Newton = 1};
LLDivMode, UsesKnuthLLDiv, UsesNewtonLLDiv(SLong only)
function It switches division routine.
form static int SLong::LLDivMode();
It returns present routine by enumerating constants above.
static void SLong::UsesKnuthLLDiv(); Knuth's method.
static void SLong::UsesNewtonLLDiv(); Newton's method
comment This library provides two division methods. Though the Knuth's method is default
one, the user can switch to Newton's method by use of "m.UsesNewtonLLDiv()" in which
"SDouble" arithmetic is used. The former is fast for short integer and the latter
for long integer. But it is difficult to get the condition which is faster.
Example
SLong a;
if(a.LLDivMode() == a.Newton) puts("Newton");
else puts("Knuth");
a.UsesNewtonLLDiv(); //uses Newton's method below
enumerating constants
function It gives the definition of values for switching the multiplication routine.
enum SLong::{ K_MULT = 0, HH_MULT = 1};
HugeMultMode
function It switches multiplication routine.
form static int SLong::HugeMultMode(); returns the present method by enumerating constants above.
static void SLong::HugeMultMode(int m); changes routine
comment This library provides recursive Karatsuba's method for the
multiplication between "huge" integers, where "huge" means a number whose figures exceed the
limit of FFT multiplication. This method needs a large memory and stack.
See a sample program "smpsqrtx.cpp" for usage. Though a statement
SLong::HugeMultMode();
is used in it, this can be rewritten as
a.HugeMultMode();
using a "SLong" object "a";
Lpow10
function "Lpow10(n)" returns 10n.
form friend SLong Lpow10(long n);
MultPowRdx
function "m.MultPowRdx(n)" changes the value of 'm' into
"mR n "(R=DRADIX or BRADIX), i.e. multiplies radix to the
nth power. 'n' can be negative.
form SLong& SLong::MultPowRdx(int n);
MultPow10 (SLong only)
function "m.MultPow10(n)" changes the value of 'm' into
"m10n, i.e. multiplies 10 to the nth power.
'n' can be negative.
form SLong& SLong::MultPow10(long n);
IsOne
function If "|m|==1", "m.IsOne()" returns the sign of
'm'(1 or -1), else returns 0.
form int SLong::IsOne() const;
Low2
function "m.Low2()" returns the lower two figures by unsigned long, i.e.
"m.figure[1]*radix + m.figure[0]".
form ulong SLong::Low2() const;
comment It does not to check that the value is initialized or not.
enumerating constants
function It gives the definition of values for output function.
form enum SLong::{ NO_CR = 0, CRLF = 1, CONTINUE = 2, LAST_CR =4 };
Put, Puts
function "m.Put(s)(...)" outputs the value of 'm' to
the present stream.
form
long SLong::Put(long fig=5, int perLine = 0, int mode = CRLF, int
delmt=' ') const;
inline long SLong::Puts(long fig=5, int perLine = 0, int mode = CRLF, int
delmt=' ') const;
comment
"m.Put()" does not output carriage return and "m.Puts()" feeds new line.
Insert delimiter given by "delmt " at intervals of "fig
" digits.
If "delmt == 0", no delimiter is inserted.
If "fig == 0", it continuously outputs with neither delimiter nor
carriage return.
"perLine" is the number of blocks which contains "fig" decimal per line.
default : "perLine = 0" automatically set "perLine =
crtWidth/(fig+1)".
Give to "mode" a value of bit sum of the following enumeration numbers
NO_CR : no '\n'
CRLF : Considering the width of display it puts a '\n' after putting an appropriate
digits.
CONTINUE : By putting '\' at the line end it makes a continuous line.
LAST_CR : It adds a '\n' at the last of output.
It returns the total number of output bytes, including '\n', and delimiter, the
same as
"printf()".
RawPut, RawPuts
function "m.RawPut(s)()" outputs the inner expression of
'm' with top zeros.
form
long SLong::RawPut(int crlf = 0) const; does not add '\n'
inline long SLong::RawPuts() const; adds '\n' at last
DFigures(SLong only)
function "m.DFigures()" returns the number of decimal digits of
'm'.
form inline long SLong::DFigures() const;
[Other related function]
Labs
function "Labs(m);" returns the absolute value of SLong integer
'm', i.e. |m|.
Its prototype declaration is given in "snfunc.h".
form inline SLong Labs(const SLong& m);