1. /* sint.h by K.Tsuru */
  2. // file id = 40 BRADIX
  3. /*********************************************************
  4. SInteger class in binary radix(BRADIX)
  5. Using the calculation factorial n!, etc.
  6. For speed the result is written on a reference argument.
  7. e.g. IIAdd(a, b, r); ---- r=a+b;
  8. But exept in a large roop, usual statements such as "r=a+b;"
  9. are allowed to use.
  10. ***********************************************************/
  11. #ifndef S_DEC_INT_H
  12. #define S_DEC_INT_H
  13. //a paramerter for the divide radix conversion SInteger to SLong
  14. // figures =< iNconvDecMaxFig : NConvToDec() is faster than DConvertTodec()
  15. const uint iNconvDecMaxFig = 225u;
  16. //a paramerter for the divide radix conversion SInteger to SLong
  17. // figures =< iNconvBinMaxFig : BSConvToBin() is faster than ConvToBin()
  18. // ver. 2.17
  19. const uint iNconvBinMaxFig = 10000u;
  20. SInteger BSConvToBin(const SLong& x); // ver. 2.17 3557
  21. SInteger SCConvToBin(const SLong& x); // ver. 2.18 3558
  22. class SInteger : public SLong {
  23. //SLong only, cannot use in this class and has no body.
  24. SInteger(const char *s);
  25. SInteger& operator=(const char *s);
  26. SInteger& MultPow10(long p);
  27. long DFigures() const;
  28. //set a double value
  29. void SetIDouble(double d); // 401
  30. public:
  31. //radix conversion DRADIX --> BRADIX
  32. SInteger NConvToBin(const SLong& m); // normal method 402. Change friend to member since version 2.20
  33. SInteger ConvToBin(const SLong& m); // ver. 2.17 402
  34. //For operator*() see below
  35. friend SInteger operator/(const SInteger& m, const SInteger& n);// 404
  36. friend SInteger operator/(const SInteger& m, double n); // 405
  37. SInteger& operator/=(const SInteger& n) { return (*this = *this / n); }
  38. SInteger& operator/=(double d) { return (*this = *this / d); }
  39. friend SInteger operator%(const SInteger& m, const SInteger& n); // 406
  40. friend SInteger operator%(const SInteger& m, double d); // 407
  41. SInteger& operator%=(const SInteger& n) { return (*this = *this % n); }
  42. SInteger& operator%=(double d) { return (*this = *this % d); }
  43. //bit operators
  44. friend SInteger operator&(const SInteger& m, const SInteger& n);//408
  45. friend SInteger operator|(const SInteger& m, const SInteger& n);//409
  46. SInteger& operator&=(const SInteger& n) { return (*this = *this & n); }
  47. SInteger& operator|=(const SInteger& n) { return (*this = *this | n); }
  48. //bit shift operator, n > 0 : to left, n < 0 : to right
  49. SInteger& BitShift(long n); // 410
  50. friend SInteger operator>>(const SInteger& m, ulong n); // 411
  51. friend SInteger operator<<(const SInteger& m, ulong n); // 412
  52. SInteger& operator>>=(ulong n) { return (*this = *this >> n); }
  53. SInteger& operator<<=(ulong n) { return (*this = *this << n); }
  54. //roughly estimated figures in DRADIX
  55. uint FigInDRadix(){
  56. double f = (double)Head()*log10((double)BRADIX)/DFIGURES + 1.0;
  57. return (uint)f +1u;
  58. }
  59. //BRADIX --> DRADIX
  60. SLong NConvToDec() const; //normal method 413
  61. SLong DConvToDec() const; //divide method by FFT 414
  62. SLong HConvToDec() const; // Horner's method(for a reference)415
  63. //Head()+1 =< iNconvDecMaxFig : NConvToDec() is faster than DConvTodec()
  64. SLong ConvToDec() const; // 416
  65. //constructors
  66. SInteger():SLong(BIN_INT, 0){}
  67. //initialized by a double value
  68. SInteger(double initialValue):SLong(BIN_INT, 0){
  69. SetIDouble(initialValue);
  70. }
  71. //by size and initial value
  72. SInteger(uint v_sz, double initialValue):SLong(BIN_INT, v_sz){
  73. if(initialValue != 0.0) SetIDouble(initialValue);
  74. }
  75. //copy constructor
  76. SInteger(const SInteger& a):SLong(a){}
  77. //SLong constructor
  78. //This cannot use for radix convesion. If use,a runtime error will occure.
  79. //This is necessary to use the operator*() of SLong class.
  80. SInteger(const SLong& a):SLong(a){
  81. if(a.Type() != BIN_INT) SetError(RADIX_ERR, "SI(SL)", 41);
  82. }
  83. //destructor
  84. ~SInteger(){} // do nothing
  85. SInteger& operator=(double d){ SetIDouble(d); return *this; }
  86. /****************************************************************************
  87. This is also necessary to use the operator*() of SLong class and cannot use
  88. for radix convesion.
  89. If an automatic radix conversion is implemented, two "=" statements
  90. 1. SL = SI*SI; ----- lhs SL has a type BIN_INT(BRADIX).Needs for operator*().
  91. 2. SL = SI; -------- call radix conversion.
  92. have different meaning each other.
  93. ****************************************************************************/
  94. SInteger& operator=(const SLong& a){
  95. if(a.Type() != BIN_INT) SetError(RADIX_ERR, "SI = SL", 42);
  96. SNumber::CopyValue(a, SUBS);
  97. return *this;
  98. }
  99. SInteger& operator=(const SInteger& a){
  100. if(this != &a) SNumber::CopyValue(a, SUBS);
  101. return *this;
  102. }
  103. //sign operator
  104. SInteger operator+() const { return *this; }
  105. //If this does not exist, a statement "t = -q/four;" is ambiguous between
  106. //SL/SL and SI/SI.
  107. SInteger operator-() const{
  108. SInteger r(*this); r.ChangeSign(417); return r;
  109. }
  110. /***************************************
  111. friend functions
  112. Set calcuration result in "SInteger& r".
  113. [Notice on specifications]
  114. The signs of m and n are arbitrary(+, - or 0) different from LLAdd(m,n).
  115. ****************************************/
  116. friend void IIAdd(const SInteger& m, const SInteger& n, SInteger& r);//r=m+n 420
  117. friend void IsAdd(const SInteger& m, fType s, SInteger& r); //r=m+s 421
  118. friend void IISub(const SInteger& m, const SInteger& n, SInteger& r);//r=m-n 422
  119. friend void IsSub(const SInteger& m, fType s, SInteger& r); //r=m-s 423
  120. friend void IsMult(const SInteger& m, ulong x, SInteger& r); //r=m*s 424
  121. //quot and remainder SI/SI, call KnuthLLDiv(m,n,r,rem) only
  122. friend void IIDiv(const SInteger& m, const SInteger& n, Ldiv_t& r, int rem);// 425
  123. //if you do not need the remainder, set rem = 0.
  124. friend void KnuthIIDiv(const SInteger& m, const SInteger& n, Ldiv_t& r, int rem); //426
  125. /**********************************************************
  126. SI/SI by Newton's method in DRADIX
  127. 1.Radix conversion m and n to SLong.
  128. 2.Call NewtonLLdiv()
  129. Due to the overhead of radix converision it is not so fast.
  130. If you want to use, please directly call this function.
  131. ************************************************************/
  132. friend void NewtonIIDiv(const SInteger& m, const SInteger& n, Ldiv_t& r, bool needRem);//427
  133. /*SInteger/(short number)*/
  134. // r = m/n (0 < n <= ULONG_MAX/BRADIX), return the remainder whose definition is same
  135. // as SLong or div() in C/C++.
  136. friend long IsDiv(const SInteger& m, ulong n, SInteger& r); // 428
  137. //Radix conversion into SLong and output it.
  138. long Put(long fig=5, int perLine = 0, int mode = CRLF, int delmt=' ') const {
  139. SLong a = ConvToDec(); // radix conversion
  140. return a.Put(fig, perLine, mode, delmt);
  141. }
  142. long Puts(long fig=5, int perLine = 0, int mode = CRLF, int delmt=' ') const {
  143. return Put(fig, perLine, mode|END_CR, delmt);
  144. }
  145. // It outputs in the four hexadecimal figures with radix = BRADIX = 2^15.
  146. // The maximum vakue of figure is "7fff".
  147. friend ostream& operator<<(ostream& os, const SInteger& m); // 430
  148. SInteger& operator+=(const SInteger& n) { IIAdd(*this, n, *this); return *this; }
  149. SInteger& operator-=(const SInteger& n) { IISub(*this, n, *this); return *this; }
  150. //++m, --n prefix. faster than m++, n-- because do not make copy.
  151. SInteger& operator++() {
  152. IsAdd(*this, 1, *this); return *this;
  153. }
  154. SInteger& operator--() {
  155. IsSub(*this, 1, *this); return *this;
  156. }
  157. //m++, n-- postfix
  158. const SInteger operator++(int){
  159. SInteger oldValue(*this);
  160. IsAdd(*this, 1, *this);
  161. return oldValue;
  162. }
  163. const SInteger operator--(int){
  164. SInteger oldValue(*this);
  165. IsSub(*this, 1, *this);
  166. return oldValue;
  167. }
  168. //operator*()
  169. //m*n If these are not provided, in "a*b+c*d" a SLong's operator+() is called.
  170. SInteger& operator*=(const SInteger& n) { return *this = LLMult(*this, n); }
  171. friend SInteger operator*(const SInteger& m, double d); //m*d 445
  172. friend SInteger operator*(double d, const SInteger& m){ return m*d; } // d*m
  173. SInteger& operator*=(double d) { return (*this = *this * d); } // apply m*d
  174. };
  175. /**********************************************************************
  176. Plus and minus operators
  177. Inside the function, IIAdd() or IISub() is called.
  178. For large roop, please directly call faster function IIAdd or IISub.
  179. ************************************************************************/
  180. inline SInteger operator+(const SInteger& m, const SInteger& n){ // m+n
  181. SInteger r(m);
  182. r += n;
  183. return r;
  184. }
  185. inline SInteger operator-(const SInteger& m, const SInteger& n) { // m-n
  186. SInteger r(m);
  187. r -= n;
  188. return r;
  189. }
  190. inline SInteger operator*(const SInteger& m, const SInteger& n) {
  191. return LLMult(m, n);
  192. }
  193. #endif // S_DEC_INT_H

sint.h : last modifiled at 2017/03/17 11:10:42(8,733 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).