Multi-Precision Arithmetic by C++ with no
use of assembler
SN library Copyright (C) 1999-2018 K.Tsuru
Reference of class functions part 7
9. SDecimal class's member and friend functions
The prototype declarations are given in "sdec.h".
This class is derived from "SDouble" class by "public" and from "SCalcInfo" structure
by "public virtual". It is a multi-precision decimal class with the radix "BRADIX" = 32,768 and fixed point. It holds an integer part in one figure which
must be less than "BRADIX". It is faster than "SDouble" class in the program in
which many multiplications or divisions between multi-precision fixed point real
number and small integer, e.g. the calculation of base of natural logarithm "E()"
by series. The floating point real number class with binary radix is not provided.
Firstly the list of unusable functions is given. The following functions can be
called via "SDouble" class object only, cannot via this class one and
have no body. Please use "XXAdd()" etc. for speed.
If you use one of them, "not accessible" error will occur. To make "operator+()", etc. compiling error, those
functions are declared in the "private" part as follows.
See the reference "Effective C++" for "operator+()".
private:
SDecimal& operator=(const SLong& sl);
SDecimal& operator=(const SFraction& sf);
SDecimal operator+(const SDecimal& m) const;
SDecimal& operator+=(const SDecimal& n);
SDecimal operator-(const SDecimal& m) const;
SDecimal& operator-=(const SDecimal& n);
SDecimal operator/(const SDecimal& m) const;
SDecimal& operator/=(const SDecimal& n);
SDecimal operator/(double d) const;
SDecimal& operator/=(double d);
SDecimal& operator=(const char *s);
SDecimal(const char *s);
void SetRdxExp(int e);
long DExp() const;
long DFigures() const;
void StdReform(int id);
SDecimal DReciprocal(const SDecimal& x);
void FixedPoint(int exp);
void PointFree();
void SizeZero();
Constructors
form
SDecimal(); default constructor
SDecimal(double d); set a value by "double"
SDecimal(const SDecimal& a); copy constructor
SDecimal(const SDouble& a);
comment The last constructor is not for the radix conversion. "a" must have type
"SNManager::BIN_DEC". See the comment for "SInteger" class's constructor.
First and second constructors allocate the memory of "figure[]"
by maximum size at the present time and initialize by zeros or given value d. The size must not be
changed until a calculation finishes. More d in second constructor must
be a finite decimal, i.e. can be converted exactly into the representation of binary
radix. Because when you use
SDecimal x(0.11....1); //'1' continues down to the fifteenth decimal
place.
it cannot be decided whether to set x=0.11....1(in fifteen significant figures) or
x=0.11....(recurring decimal). If you want to set "0.1" etc. , once substitute it for a SDouble
object and convert into binary (e.g. using fourth constructor). This situation is the same
as that of the
substitution operator below.
substitution operators
form
SDecimal& operator=(double d); See above.
SDecimal& operator=(const SDouble& a);
SDecimal& operator=(const SDecimal& x);
comment The second operator is provided for use of "SDouble" class's multiplication
and "a" must have type "SNManager::BIN_DEC".
relation operators >, <, ==, !=, >=, <=, ||, &&, !
This class inherits these operators of "SDouble" class.
fundamental operation functions
To avoid the overhead by memory copy, the obtained result is set in an argument
"SDecimal& r ". Then the operators +,-,/, etc. are not provided. Only the operator
'*' can be used.
form
friend void XXAdd(const SDecimal& m, const SDecimal& n, SDecimal&
r ); r =m +n
friend void XXSub(const SDecimal& m, const SDecimal& n, SDecimal&
r ); r =m -n (|m|>=|n| must be
satisfied)
friend void XsMult(const SDecimal& m, ulong s, SDecimal& r
); r =m *s
friend void XsDiv(const SDecimal& m, ulong s, SDecimal& r
); r =m/s
comment
In "XXSub(m, n, r );" |m|>=|n| must be
satisfied, because it does not check which is greater to avoid the overhead. If
you cannot know the relation between two operands m and n, please
use the relational operators > or <. In "XsMult(m,
s, r );" and "XsDiv(m, s, r );" the operand s must be smaller than
"ULONG_MAX/BRADIX"(=131072 for the system in which "unsigned long" has 32 bits).
BitShift
function "x.BitShift(p )" changes the value of x into 2p
x.
form SDecimal& SDecimal::BitShift(long p );
comment The result 2p x must be less than BRADIX.
If not, an overflow error will occur.
ConvToBin
function "ConvToBin(SD )" returns the expression in the binary
radix (SDecimal) of SD.
from friend SDecimal ConvToBin(const SDouble& sd);
ConvToDec
function "x..ConvToDec()" returns the expression in the decimal
radix (SDouble) of x..
form inline SDouble SDecimal::ConvToDec() const;
comment
The following two functions are provided for the radix conversion.
SDouble NConvToDec() const; normal method
SDouble DConvToDec() const; divide method by use of FFT multiplication.
If "Head() + 1 > dNconvDecMaxFig" "DConvToDec()" is faster than "NConvTodec()".
Where "dNconvDecMaxFig" is defined in "sdec.h".
"ConvToDec()" calls faster function
between above.
Put, Puts
function "x .Put(s)(...)" makes the radix conversion of x into "SDouble" and
outputs it.
form
long SDecimal::Put(long fig =5, long pr = 0, int perLine =0, int
mode = CRLF|ROUND|INT_PUT, int delmt =' ') const;
inline long SDecimal::Puts(long fig =5, long pr = 0, int perLine
=0, int mode = CRLF|ROUND|INT_PUT, int delmt =' ') const;
comment The meaning of arguments are the same as those of "SDouble" class.