1. /* snum.h by K.Tsuru */
  2. // error ID = 1x
  3. /*----------------
  4. SNumber class
  5. ------------------*/
  6. #ifndef S_NUMBER_H
  7. #define S_NUMBER_H
  8. typedef NCBlock<fType> FigBlock; // type of figure[]
  9. /****************** sub-functions ************************/
  10. /*---------------------------------------------------------------------
  11. FigBlock shift to upper(n>0)/lower(n<0)
  12. Do not enlarge the size, i.e. cut off an oversize area.
  13. If abs(n) >= a.size(), "a" is initialized by zero.
  14. -----------------------------------------------------------------------*/
  15. int FigBlockShift(FigBlock& a, int n);
  16. /*-------------------------------------------------------------
  17. Convert x into a number "r" in radix "DRADIX", i.e. in a form
  18. x = r[0].r[1].... x DRADIX^e, r[0] = 0
  19. Return the exponent "e".
  20. --------------------------------------------------------------*/
  21. int doubleToArray(double x, FigBlock& r, uint *size);
  22. int ldoubleToArray(ldouble x, FigBlock& r, uint *size);
  23. /*-----------------------------------------------------------------------------
  24. Try to convert double "d" using long "L" into a form
  25. d = L * 10^e ( 0 =< |L| <= mt).
  26. When it is successed, return true. The operation between SDouble and double can
  27. be reduced into one between SDouble and short integer.
  28. e.g. x/1.3 ---> (x/13000)*DRADIX.
  29. Usually take mt = (double)d.SlOpMaxValue() (= ULONG_MAX/radix);
  30. -------------------------------------------------------------------------------*/
  31. bool doubleTolongExp(double d, long* L, int* e, double mt);
  32. /******************** end of sub-functions ***********************/
  33. /********************
  34. The list of classes
  35. D(DRADIX), B(BRADIX)
  36. *********************/
  37. // error/function ID
  38. class SNumber; // 1xx
  39. class SLong; // integer(D) 2xx
  40. class SDouble; // floating point number(D) 3xx
  41. class SInteger; // integer(B) 4xx
  42. class SDecimal; // fixed point number(B) 5xx
  43. class StringToNumber; // string -->integer/real 6xx
  44. class SFraction; // Fraction(D) 7xx
  45. class SRational; // Rational(B) 8xx
  46. class SComplex; // complex(D) 9xxx ver.2.18
  47. class SLComplex; // complex(D) 9xxx ver.2.182
  48. // template class 1xxx
  49. struct Ldiv_t; // structure 27x
  50. /****************
  51. for preprocessor ver 2.18
  52. ****************/
  53. #define SNUMBER 1
  54. #define SLONG 2
  55. #define SDOUBLE 3
  56. #define SDEC_INT 4
  57. #define SDECIMAL 5
  58. #define SFRACTION 7
  59. #define SRATIONAL 8
  60. /***********************************************
  61. Provides common parts of multi-precision number
  62. ************************************************/
  63. class SNumber : public SNManager{
  64. // Do not use default constructor and operator=().
  65. SNumber(); // has no body.
  66. SNumber& operator=(const SNumber& sn); // has no body.
  67. // table of cutDown (ENABLE | DISABLE), the size can be reduced or not
  68. static bool cutDownTable[DETECT_IR];
  69. uchar pushCD; // change cutDownTable[] 1 / 0
  70. signed char sign; // sign(-1,0,1 or UNDECIDED)
  71. NumberType type; // type of multi-precision number
  72. public:
  73. /*****************************************************************
  74. Definition of values of "pushCD" for changing the value of "cutDown".
  75. POP : back to previous value
  76. PUSH bit is on for an object which change the value of "cutDown".
  77. defined enum { DISABLE = 0, ENABLE = 1}; in "snconst.h"
  78. ******************************************************************/
  79. enum { POP = 2, PUSH = 4 };
  80. /**********************************************
  81. Definition of values for sign
  82. UNDECIDED : figure[] is not initialized or empty
  83. ***********************************************/
  84. enum { MINUS = -1, ZERO = 0, PLUS = 1, UNDECIDED = 0x10 };
  85. protected :
  86. //position of non-zero figures
  87. //figure[]:f[0]...f[aTail]...f[aHead]...f[size-1]
  88. //value : 0 ...0(t>0) ... (h>0)0 ... 0
  89. uint aHead;
  90. uint aTail;
  91. FigBlock figure; // variable size array
  92. void SetType(NumberType tp){ type = tp; }
  93. /***************************************************************
  94. allocates memory of figure[]
  95. Do not free memory. Use "SizeZero()" for free memory.
  96. Decides the sign by initialization. sign
  97. copy=0:all elements are initialized by zero ZERO
  98. copy>0:copy lower elements,upper initialized by zero ----
  99. copy<0:allocate memory only,do not initialize UNDECIDED
  100. return figure.size()
  101. Even if sz > minArraySize, "CutDown(DISABLE)" is not done.
  102. ****************************************************************/
  103. uint valloc(uint sz, int copy); // 101
  104. /*************************************************************************
  105. Allocate memory to be possible to substitute the element figure[index].
  106. The extended part is initialized by zero. For integer type(SLong/SInteger)
  107. if index>=maxmum size, the program terminate by overflow error.
  108. return success(1)/not(0)
  109. ****************************************************************/
  110. bool Reserve(uint index){
  111. if(index < figure.size()) return 1;
  112. valloc(index+1, 1); // do not use "figure.reserve()"
  113. return (index < figure.size()) ? 1 : 0;
  114. }
  115. /******************************************************
  116. Get the position of figure[aTail] and figure[aHead].
  117. Give id the position ID number of function for debug.
  118. ******************************************************/
  119. void CheckArray(int id); // 102
  120. /****************************************************
  121. Shift figure[] to upper(shift>0) or lower(shift<0).
  122. Move figure[i] to figure[i+shift].
  123. The values of "aHead" and "aTail" should be decided.
  124. return the sign or zero if out of range by moving.
  125. ******************************************************/
  126. int ShiftArray(int shift); // 103
  127. /*******************************************************************
  128. copy function
  129. cs=COPY:set "figure = a.figure" for copy constructor.
  130. cs=SUBS:change the size of figure[] for the operator=()
  131. ********************************************************************/
  132. enum { COPY = 1, SUBS = 2 };
  133. void CopyValue(const SNumber& a, int cs); // 104
  134. /*****************************************************
  135. normalization function
  136. Do not call "CheckArray()".
  137. The values of "aHead" and "aTail" should be decided.
  138. Used in "operator()++", etc.
  139. ******************************************************/
  140. void Normalize(); // 105
  141. /****************************************************************************
  142. CutDown
  143. Reduce the size of figure[] by cutting upper/lower zeros for integer/real number.
  144. When the size of result after the operation is less than half of previous one,
  145. call this function.
  146. CutDown(DISABLE) take into a mode in which the size of figure[] is not reducible.
  147. Mainly used in the fixed-point mode in "SDouble" function.
  148. See also the function "BdFact(n)".
  149. ****************************************************************************/
  150. void CutDown(uchar cd); // cd = DISABLE , ENABLE or POP. 106
  151. void DoCutDown(); // reudce size if ENABLE 107
  152. uchar PushedCD() const { return pushCD; }
  153. void PushCD(uchar cd) { pushCD = cd; }
  154. // check sign
  155. void SignCheck(int id) const{
  156. // Trying to take out the sign of uninitialized value causes error.
  157. if(sign == UNDECIDED) SetError(UNDEC_VALUE, NULL, id);
  158. #ifndef NDEBUG
  159. else assert( (sign == ZERO) || (sign == PLUS) || (sign == MINUS) );
  160. #endif
  161. }
  162. void SetSign(double s){
  163. if(s == 0.0) sign = ZERO;
  164. else sign = s > 0 ? PLUS : MINUS;
  165. }
  166. public:
  167. // type & DETECT_IR = DEC_INT or REAL.
  168. bool CutDown() const {
  169. return (type == BIN_DEC) ? DISABLE : cutDownTable[type & DETECT_IR];
  170. }
  171. /****************************************
  172. Set a number by use of FigBlock and sign.
  173. Do not call Normalize().
  174. *****************************************/
  175. void SetFigBlock(const FigBlock& a, int sgn); // 108
  176. // version in which call Normalize()
  177. void SetFigBlockNorm(const FigBlock& a, int sgn){
  178. SetFigBlock(a, sgn); Normalize();
  179. }
  180. /*****************************************************
  181. Set all elements of figure[] and sign zero.
  182. If cutDown==ENABLE, reduce the size to minArraySize.
  183. *****************************************************/
  184. virtual void SetZero(); // 109
  185. uint Head() const { return aHead; }
  186. uint Tail() const { return aTail; }
  187. /*************************************************************
  188. Read elements of figure[] via pointer. Faster than operator().
  189. [usage] const fType* mv = m.ReadFigures();
  190. .... mv[] can be used as right hand side/not lhs......
  191. reference:"Effective C++"
  192. *************************************************************/
  193. const fType* ReadFigures() const {
  194. SNumber* const temp = (SNumber* const)this;
  195. return temp->figure.Elements();
  196. }
  197. /************************************************************
  198. Read figure[] by FigBlock&.
  199. Provides a method which change a part of figure[] and make a
  200. new object by use of SetFigBlock().
  201. [usage]const FigBlock& mv = m.FigBlock(); // take out figure[]
  202. FigBlock a(mv); // copy
  203. ...change the a.figure[]....
  204. x.SetFigBlock(...);
  205. ************************************************************/
  206. const FigBlock& ReadFigBlock() const {
  207. SNumber* const temp = (SNumber* const)this;
  208. return temp->figure;
  209. }
  210. // free memory
  211. void SizeZero(){
  212. sign = UNDECIDED; aHead = aTail = 0; figure.size(0, 0);
  213. }
  214. /************************************************************************
  215. Provides a user's method to allocate memory of figure[].
  216. The meaning of "copy" is same as that of "valloc()".
  217. If size > minArraySize, "CutDown(DISABLE)" is called.
  218. *************************************************************************/
  219. void FigureAlloc(uint size, int copy = 0); // 110
  220. void FigureClear(uint from, uint to); // 111 ver. 2.17
  221. //Make the size to be smaller if possible in "DISABLE" mode.
  222. void ReduceSize(){
  223. if( 2u*(aHead+1u) <= figure.size() ){
  224. CutDown(ENABLE); valloc( aHead+1u, 1); CutDown(POP);
  225. }
  226. }
  227. /*************
  228. various sizes
  229. **************/
  230. uint MaxSize() const { return SNMaxSize(type); }
  231. virtual uint MinSize() const { return minArraySize; }
  232. uint FigureSize() const { return figure.size(); }
  233. virtual uint Size() const { // override in SDouble class
  234. return min(figure.size(), SNMaxSize(type));
  235. }
  236. //Standard multiplication in BRADIX is faster twice that in DRADIX.
  237. uint FFTMinSize() const{
  238. return (type & BIN_RDX) ? 2u*MFFTMinSize() : MFFTMinSize();
  239. }
  240. uint FFTMinSize(NumberType tp) const{
  241. return (tp & BIN_RDX) ? 2u*MFFTMinSize() : MFFTMinSize();
  242. }
  243. // radix
  244. fType Radix() const { return (type & BIN_RDX) ? BRADIX : DRADIX; }
  245. ulong RadixSq() const { return (type & BIN_RDX) ? BRADIX_SQ : DRADIX_SQ; }
  246. //Maximum value of small number in operation (SXXX)/(ulong).
  247. ulong SlOpMaxValue() const {
  248. return (type & BIN_RDX) ? ULONG_MAX/(ulong)BRADIX : ULONG_MAX/(ulong)DRADIX;
  249. }
  250. // constructor
  251. // do not allocate memory of figure[]
  252. SNumber(NumberType tp):pushCD(0), sign(UNDECIDED), type(tp),
  253. aHead(0), aTail(0), figure(){ objectCounter++; }
  254. /**************************************************
  255. fsz:size of figure[]
  256. sign = UNDECIDED;
  257. If fsz == 0, do not allocate memory of figure[].
  258. ***************************************************/
  259. SNumber( NumberType tp, uint fsz); // 111
  260. //copy constructor
  261. //Do not copy "pushCD",i.e. not initialize as pushCD(a.pushCD).
  262. SNumber(const SNumber& a) : pushCD(0), sign(a.sign), type(a.type),
  263. aHead(a.aHead), aTail(a.aTail) , figure(a.figure){ objectCounter++; }
  264. // destructor
  265. virtual ~SNumber(); // Restore cutDownTable[] value. 112
  266. /*************************************************************
  267. For read(lhs) only
  268. Do not use in large for() roop, because of much overhead time.
  269. **************************************************************/
  270. fType operator()(int n) const { // "SNumber::" is deleteted since version 2.912.
  271. if(n < 0) return 0;
  272. return ( (uint)n < figure.size() ) ? figure(n) : 0;
  273. }
  274. /*******************************************************************
  275. return raw value without cheking the range of n and size of figure[].
  276. Use when you are sure that n < figure.size().
  277. Can not used as lhs. For writting use SetFigBlock(const FigBlock& a,int sgn);
  278. *********************************************************************/
  279. fType operator[](uint n) const { return figure(n); }
  280. NumberType Type() const { return type; }
  281. virtual int Sign(int id = 11) const { SignCheck(id); return (int)sign; }
  282. int RawSign() const { return (int)sign; }
  283. /**************************************************************
  284. Faster than the statement "r = -r;" which call copying routine.
  285. ***************************************************************/
  286. void ChangeSign(int id = 13){ SignCheck(id); sign = -sign; }
  287. };
  288. inline fType Radix(SNumber::NumberType tp) {
  289. return (tp & SNManager::BIN_RDX) ? BRADIX : DRADIX;
  290. }
  291. #endif // S_NUMBER_H

snum.h : last modifiled at 2017/08/20 11:53:05(13,013 bytes)
created at 2016/04/11 11:18:59
The creation time of this html file is 2017/10/11 16:07:52 (Wed Oct 11 16:07:52 2017).