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.