1. /* slong.h by K.Tsuru */
  2. // file ID = 20
  3. #ifndef S_LONG_H
  4. #define S_LONG_H
  5. /******************
  6. SLong class
  7. *******************/
  8. class SLong : public SNumber{
  9. friend class SInteger;
  10. friend class SDouble; // LLMult() accesible
  11. friend struct Ldiv_t; // SetType() accesible
  12. SLong& operator=(const SInteger& si); // has no body
  13. protected :
  14. void SetString(const char *s); //set a number by string into figure[] 201
  15. void SetDouble(double d); // double or long 202
  16. void SetSDouble(const SDouble& sd); // 203
  17. int CharNthFig(long n) const; //see source file "slmput.cpp" 204
  18. public :
  19. // fft is usable or not
  20. bool FFTMultUsable() const; // inline function defined bellow
  21. // Radix conversion DRADIX --> BRADIX XConvToBin() was moved into the class SInteger.
  22. //set a short number, m = 1 can be used but for speed
  23. void SetLong(long v); // 205
  24. void SetShort(short v); // 206 v within two figures
  25. void SetSmall(signed char v); // 207 one figure
  26. void SetInt(int v){ SetLong(v); } // an inline function Ver.2.18
  27. //It estimates the number of figures in binary radix(BRADIX).
  28. uint FigInBRadix(){
  29. double f = (double)Head()*(double)DFIGURES/log10((double)BRADIX) + 1.0;
  30. return (uint)f;
  31. }
  32. // constructor
  33. SLong():SNumber(DEC_INT){}
  34. SLong(double d):SNumber(DEC_INT){ SetDouble(d); }
  35. SLong(const char* s):SNumber(DEC_INT){ SetString(s); }
  36. //If this constructor exists SD*SL yelds an ambiguous error in which
  37. //it cannot distinguish SD*SD or SL*SL.It is natural to convert SD*SL into SD*SD.
  38. //Use SL = SD.
  39. #if 0
  40. SLong(const SDouble& a):SNumber(DEC_INT){
  41. SetSDouble(a);
  42. }
  43. #endif
  44. /*
  45. Specifying the type and size.
  46. When the necessary size is previously known use this constructor.
  47. When v_sz > minArraySize it takes into the irreducible size mode.
  48. When v_sz = 0 it does not allocate the memory of figure[].
  49. */
  50. SLong(NumberType tp, uint v_sz):SNumber(tp, v_sz){
  51. if(v_sz) SetZero(); //initialized by zero
  52. }
  53. //Specifying an initial value.
  54. SLong(NumberType tp, uint v_sz, double initialValue):SNumber(tp, v_sz){
  55. SetDouble(initialValue);
  56. }
  57. // destructor
  58. ~SLong(){}
  59. // copy constructor
  60. SLong(const SLong& a):SNumber(a){}
  61. //substitution operators
  62. SLong& operator=(const char *s) { SetString(s); return *this; }
  63. SLong& operator=(double m){ SetDouble(m); return *this; }
  64. SLong& operator=(const SDouble& sd){
  65. SetSDouble(sd); return *this;
  66. }
  67. #if 0
  68. //These are not implemented. See SInteger class for the reason.
  69. SLong(const SInteger& si):SNumber(DEC_INT){
  70. SetSInteger(si);
  71. }
  72. SLong& operator=(const SInteger& si){
  73. SetSInteger(si); return *this;
  74. }
  75. #endif
  76. SLong& operator=(const SFraction& sf); // return *this = sf.NumNR()/sf.DenNR(); // defined in "sfract.h"
  77. // Above cannot be the inline function because SFraction's functions are not given here.
  78. SLong& operator=(const SLong& a){
  79. if(this != &a) SNumber::CopyValue(a, SUBS);
  80. return *this;
  81. }
  82. SLong& operator=(const Ldiv_t& a); // inline function
  83. //It compares two absolute values and returns the same value as that of strcmp().
  84. friend int LLCompare(const SLong& m, const SLong& n); // 206
  85. //sub-functions for the fundamental operators.
  86. friend SLong LLAdd(const SLong& m, const SLong& n); // m+n (m and n have same sign) 207
  87. friend SLong LLSub(const SLong& m, const SLong& n); // m-n 208
  88. friend SLong LLMult(const SLong& m, const SLong& n);// m*n 209
  89. //normal method for the multilication
  90. friend SLong NLLMult(const SLong& m, const SLong& n);// 210
  91. //divide multiplication for the size less than fftMaxSize
  92. friend SLong DivLLMult(const SLong& m, const SLong& n); // 211
  93. friend SLong LsMult(const SLong& m, ulong n); // 212
  94. //If rem != NULL it sets remainder into *rem.
  95. friend SLong LsDiv(const SLong& m, ulong n, long* rem = NULL);// 213
  96. /*
  97. division for long numbers
  98. In KnuthLLDiv or NewtonLLDiv it is assumed thet the checking m > n > ULONG_MAX/m.Radix()
  99. etc is already done in LLDiv().Pay attention for the direct call.
  100. NewtonLLDiv can be used for SLong with radix DRADIX.
  101. If you do not need the remainder set "rem" by false.
  102. To avoid wrong use these functions are the protected members. ver. 2.81
  103. */
  104. protected:
  105. Ldiv_t NewtonLLDiv(const SLong& m, const SLong& n, bool needRem);// 214
  106. Ldiv_t KnuthLLDiv(const SLong& m, const SLong& n, bool needRem); // 215
  107. static int llDivMode;
  108. public:
  109. friend Ldiv_t LLDiv(const SLong& m, const SLong& n, bool needRem); // 216
  110. friend SLong LLDiv(const SLong& m, const SLong& n); // 217 introduced since ver. 2.30
  111. enum { reset = 0, Knuth = 1, Newton = 2, SetByUser = 8 };
  112. // Do not add ") const {" to static functions
  113. static void SetLLDivMode(int dm) { llDivMode = dm ? (dm | SetByUser) : dm; }
  114. static int LLDivMode() { return llDivMode & 3; } // return lower 2 bits.
  115. static void UseKnuthLLDiv() { SetLLDivMode(Knuth); }
  116. static void UseNewtonLLDiv(){ SetLLDivMode(Newton); }
  117. //It designates to use whether KnuthLLDiv or NewtonLLDiv routine.
  118. //For many figures the Newton's method is faster.
  119. static bool KnuthLLDivIsFaster(const SLong& m, const SLong& n) {
  120. uint mf = m.Head(), nf = n.Head();
  121. return (diff(mf, nf) > 10u) && (mf + nf < 400u); // diff(a,b) = |a-b|
  122. }
  123. static bool NewtonLLDivIsFaster(const SLong& m, const SLong& n) {
  124. return !KnuthLLDivIsFaster(m, n);
  125. }
  126. /*
  127. For huge number over 'fftMaxArraySize'.
  128. */
  129. private:
  130. // huge * huge
  131. // default values : hhMultMode = Karatsuba_HH_MULT, pfHHMult = DisKHHMult ver. 2.17
  132. // default values : usesKaratsuba_HH_Mult = true
  133. // static int hhMultMode; //
  134. static bool usesKaratsuba_HH_Mult;
  135. // static void (*pfHHMult)(const SLong& x, const SLong& y, SLong& z); // 209
  136. public:
  137. // Do not add ") const {" to static functions
  138. static void KaratsubaMultSwitch(bool a) { usesKaratsuba_HH_Mult = a; }
  139. static bool UsesKaratsubaMult() { return usesKaratsuba_HH_Mult; }
  140. /*
  141. FFT multiplication.
  142. It does not depend on radix.
  143. */
  144. uint FFTMaxArraySize() const {
  145. return (Type() == DEC_INT) ? fftMaxArraySize : fftMaxArraySize/8u; // "/4u" --> "/8u" since version 2.30
  146. }
  147. // protected: for test
  148. // member functions in protected section from friend ones.
  149. // z = x*y
  150. void LLMultFFT(const SLong& x, const SLong& y, SLong& z, uint n); // z = x*y 217
  151. protected:
  152. /*
  153. z = (huge x) * (huge y)
  154. */
  155. //normal method (default) It needs rather small memory.
  156. //In the following three functions it must be satisfied that &z!=&x and &z!=&y.
  157. //Using as xxxHHNult(x,y,x) yileds a run time error.
  158. // Normal method using distribution law
  159. void NHHMult(const SLong& x, const SLong& y, SLong& z); // 218
  160. // Karatsuba's multiplication using recursive calls.
  161. //z = (huge x) * (huge y) for x.Size() >= y.Size(), distribution method(Karatsuba's multiplication)
  162. void KaratsubaHHMult(const SLong& x, const SLong& y, SLong& z); // 219
  163. //z = (huge x) * (huge y) for x.Size() == y.Size() same size
  164. //It provides the Karatsuba's multiplication using recursive calls.
  165. //It needs a large memory.
  166. void KHHMult(const SLong& x, const SLong& y, SLong& z); // 220
  167. /*
  168. It puts the lower part of x into "lower" and the upper part into "upper".
  169. sub-function for KHHMult()
  170. */
  171. void SLDivHalf(const SLong& x, SLong& lower, SLong& upper); // 221
  172. /*
  173. It cuts out from src[pos] with a length "size" and puts into
  174. dest[0]...dest[size-1]. It attaches the same sign to "dest" as that of "src".
  175. If pos > src.Head() dest=0.
  176. */
  177. void SLCutOut(SLong& dest, const SLong& src, uint pos, uint size); // 222
  178. public:
  179. //fundamental operators
  180. friend SLong operator+(const SLong& m, const SLong& n); // m+n not "return LLAdd(m, n)" 224
  181. friend SLong operator-(const SLong& m, const SLong& n); // m-n not "return LLSub(m, n)" 225
  182. //multiplication/division If n is small LsMult() or LsDiv() is faster. // 226
  183. friend SLong operator*(const SLong& m, double d); // m*d 227
  184. friend SLong operator*(double d, const SLong& n){ return n*d; }
  185. // friend SLong operator/(const SLong& m, const SLong& n); // defined below as inline function since ver. 2.30
  186. friend SLong operator/(const SLong& m, double d); // 229
  187. friend SLong operator%(const SLong& m, const SLong& n); // 230
  188. friend SLong operator%(const SLong& m, double d); // 231
  189. SLong& operator+=(const SLong& n) { return (*this = *this + n); }
  190. SLong& operator-=(const SLong& n) { return (*this = *this - n); }
  191. SLong& operator*=(const SLong& n) { return *this = LLMult(*this, n); }
  192. SLong& operator*=(double d) { return (*this = *this * d); }
  193. SLong& operator/=(const SLong& n) { return *this = LLDiv(*this, n); }
  194. SLong& operator/=(double d) { return (*this = *this / d); }
  195. SLong& operator%=(const SLong& n) { return (*this = *this % n); }
  196. SLong& operator%=(double d) { return (*this = *this % d); }
  197. void LsAdd(fType a); //It adds a small value. It is used in the radix convesion. 232
  198. //I do not have LsSub().
  199. void LsPlus(fType a); //sub-function for operator++() 233
  200. void LsMinus(fType a); //operator--() 234
  201. //It divides by two. Except a large routine use m/2 or LsDiv(m,2).
  202. //To judge even or odd see the value of n(0) % 2.
  203. friend SLong LDiv2(const SLong& n); // 235
  204. /*
  205. It divides m by the p-th power of two, i.e. q=m/(2^p),
  206. where 2^p < ULONG_MAX/radix. It returns the remainder.
  207. Comparing a statement
  208. q = LsDiv(m, 1uL << p);
  209. it is faster a few times. It is used in ReduceByPow2Rdx(), etc.
  210. */
  211. friend long LDivPow2(const SLong& m, SLong& q, uint p); // 236
  212. //prefix increment and decrement operators
  213. SLong& operator++(){ LsPlus(1); return *this; }
  214. SLong& operator--(){ LsMinus(1); return *this; }
  215. //postfix incremant and decrement operators
  216. //See the source file "slopppsf.cpp" for details.
  217. const SLong operator++(int){// to inline function since ver. 2.30
  218. SLong oldValue(*this); // keep the old value
  219. LsPlus(1); // add one
  220. return oldValue; // return the old value
  221. }
  222. const SLong operator--(int){// see above
  223. SLong oldValue(*this);
  224. LsMinus(1);
  225. return oldValue;
  226. }
  227. // bit(& | >> <<) operators
  228. friend SLong operator&(const SLong& m, const SLong& n); // 241
  229. friend SLong operator|(const SLong& m, const SLong& n); // 242
  230. friend SLong operator>>(const SLong& m, ulong n); // 243
  231. friend SLong operator<<(const SLong& m, ulong n); // 244
  232. SLong& operator>>=(ulong n) { return (*this = *this >> n); }
  233. SLong& operator<<=(ulong n) { return (*this = *this << n); }
  234. SLong& operator&=(const SLong& n) { return (*this = *this & n); }
  235. SLong& operator|=(const SLong& n) { return (*this = *this | n); }
  236. private: // Has no body and cannot use.
  237. SLong operator^(const SLong& m) const;
  238. SLong& operator^=(const SLong& n);
  239. SLong operator~() const;
  240. public:
  241. //It multiplies by n-th power of radix(DRADIX, BRADIX).
  242. SLong& MultPowRdx(int n){
  243. if(Sign(21) && n) ShiftArray(n);
  244. if(Sign() && (n < 0) ) DoCutDown();
  245. return *this;
  246. }
  247. //It multiplies by p-th power of ten 10. DRADIX only
  248. SLong& MultPow10(long p); // 251
  249. //It returns the number of figures in a decimal system. DRADIX only
  250. long DFigures() const; // 252
  251. //sign operators
  252. SLong operator+() const { return *this; }
  253. SLong operator-() const { // Move into inline since ver. 2.30
  254. SLong r(*this);
  255. r.ChangeSign(253);
  256. return r;
  257. }
  258. // |*this| == 1 or not. When true it returns the sign(1 or -1).
  259. int IsOne() const {
  260. if(aHead) return 0;
  261. return figure(0) == 1 ? Sign(22) : 0;
  262. }
  263. //It returns the lower two figures by unsigned long. It does not to check
  264. //that the value is initialized or not.
  265. ulong Low2() const {
  266. return (ulong)figure(1)*(ulong)Radix() + (ulong)figure(0);
  267. }
  268. /****************************************************************************
  269. output functions
  270. Put() : not carridge return, Puts() : feed new line
  271. Insert delimiter given by "delmt" at intervals of "fig" characters.
  272. If delmt == 0, no delimiter is inserted.
  273. If fU (figUnit) == 0, it continuously outputs with neither delimiter nor carridge return.
  274. perLine = the number of blocks which contains "fig" decimal per line
  275. default : perLine = 0 automatically set perLine = displayWidth/(fig+1)
  276. Give to "lineFormat" a value of bit sum of the following enumeration numbers
  277. NO_CR : no '\n'
  278. CRLF : Considering the width of display it puts a '\n' after putting an appropriate
  279. digits.
  280. CONTINUE : By putting '\' at the line end it makes a continuous line.
  281. END_CR : It adds a '\n' at the last of output.
  282. ***********************************************************************/
  283. static long figUnit;
  284. static int perLine;
  285. static int lineFormat;
  286. static int delmt;
  287. static long ioCount; // the number of input or output characters
  288. enum { NO_CR = 0, CRLF = 1, CONTINUE = 2, END_CR =4 };
  289. static void SetFormat(long fU, long pL = 0, int lF = CRLF, int dm = ' ');
  290. static void DefaultFormat(); // It restores the default values.
  291. long Put(long fU=10, int pL = 0, int lF = CRLF, int dlmt=' ') const; // 261
  292. // If fU < 0 parameters by SetFormat() are used example Put(-1);
  293. long Puts(long fU=10, int pL = 0, int lF = CRLF, int dlmt=' ') const;
  294. //It outputs the inner expression.
  295. long RawPut(int crlf = 0) const; // 262
  296. long RawPuts() const { return RawPut(1); }
  297. friend ostream& operator<<(ostream& os, const SLong& sl); // 263 added since version 2.21
  298. };
  299. /******************** End of SLong class ********************/
  300. inline SLong operator/(const SLong& m, const SLong& n){
  301. return LLDiv(m, n);
  302. }
  303. inline SLong operator*(const SLong& m, const SLong& n) {
  304. return LLMult(m, n);
  305. }
  306. //The FFT multiplication can be done by calling once or not.
  307. inline bool SLong::FFTMultUsable() const {
  308. return ( 2u*aHead < fftMaxArraySize ) && FFTUse() && (aHead >= FFTMinSize());
  309. }
  310. //It returns the number of figures. SLong class only
  311. inline long SLong::DFigures() const{
  312. if( !Sign(23) ) return 0;
  313. return (long)iFigures(figure(aHead)) + (long)aHead*(long)DFIGURES;
  314. }
  315. inline long SLong::Puts(long fig, int perLine, int lineFormat, int delmt) const {
  316. long l = Put(fig, perLine, lineFormat|END_CR, delmt);
  317. FPutc('\n');
  318. return l+1;
  319. }
  320. /***********************************************************************
  321. It defines a structure which has a quotient and a remainder as members,
  322. i.e. the SLong version of div_t.
  323. x = q*y + r
  324. The quotient is decided by q = x/y and the remainder by r = x - q*y.
  325. It can be r < 0. For example
  326. x = -5, y = -2
  327. (-5)/(-2) = 2 = q, -5 = 2*(-2) -1
  328. then r = -1.
  329. *************************************************************************/
  330. struct Ldiv_t{
  331. friend class SLong;
  332. SLong quot; //quotient : a public member
  333. SLong rem; //remainder
  334. //default constructor
  335. Ldiv_t(): quot(), rem(){}
  336. // Ldiv_t f(){ return 0.0; } can be used.
  337. Ldiv_t(double q):quot(q), rem(0.0){}
  338. // return Ldiv_t(q, m);
  339. Ldiv_t(const SLong& q, const SLong& r):quot(q), rem(r){}
  340. // return q
  341. Ldiv_t(const SLong& q):quot(q), rem(q.Type(), minArraySize){}
  342. // copy constructor.
  343. Ldiv_t(const Ldiv_t& m); // 275
  344. //substitution oparator
  345. Ldiv_t& operator=(const Ldiv_t& a){
  346. if(this != &a){
  347. quot = a.quot; rem = a.rem;
  348. }
  349. return *this;
  350. }
  351. };
  352. //substitution operator SLong = Ldiv_t
  353. //a member of SLong class
  354. //This is defined here where the structure of Ldiv_t is known.
  355. inline SLong& SLong::operator=(const Ldiv_t& a){
  356. return *this = a.quot;
  357. }
  358. /* defined in template
  359. inline istream& operator>>(istream& s, SLong& a) // added since version 2.21
  360. {
  361. string buf;
  362. std::getline(s, buf); // usage : cin >> a; ( s = cin )
  363. a = buf.data();
  364. return s;
  365. }
  366. */
  367. static const SLong SL_ONE(1.0);
  368. #endif // S_LONG_H

slong.h : last modifiled at 2017/07/17 16:58:58(15,716 bytes)
created at 2016/04/11 11:18:58
The creation time of this html file is 2017/10/11 16:07:52 (Wed Oct 11 16:07:52 2017).