1. /* sfract.h by K.Tsuru */
  2. // file ID = 700 DRADIX
  3. /****************************************
  4. SFraction class using SLong arithmetric
  5. See SRational class
  6. ******************************************/
  7. /***********************************************************************
  8. About the timing of reduction.
  9. 1)#define REDUCE_SIZE 0 // below
  10. If it would be done every time after an operation, it takes many times.
  11. 2)#define REDUCE_SIZE 1 // below
  12. Then the ruduction is called when
  13. 1.maximum figure of numerator and denominator exceeds a threshold value.
  14. 2.output function is called.
  15. 3."Reduce()" is called.
  16. Speed depends on the sytem FPU and OS. On my machine 1) is faster about twice.
  17. Please try/test on your system.
  18. ************************************************************************/
  19. #ifndef S_FRACTION_H
  20. #define S_FRACTION_H
  21. #define REDUCE_SIZE 0 // reduceSize = 0; reduceStepByStep = true; Knuth's method is used.
  22. class SFraction {
  23. SLong num, den; //"num" has the sign and "den" is always positive.
  24. bool reduceDone;
  25. #if REDUCE_SIZE != 0
  26. static uint reduceSize; //a threshold value for reduction
  27. static bool reduceStepByStep; // Knuth's method is used or not.
  28. void reduce(bool must); //701 do reduce
  29. #endif
  30. void reduce(); //701 do reduce
  31. void SetString(const char *s); // 702
  32. SFraction& operator=(const SDouble& a); // has no body
  33. SFraction& operator=(const SDecimal& a); // has no body
  34. SFraction& operator=(const SInteger& a); // has no body
  35. void DenCheck(); // 703
  36. void RadixCheck() const; // inline function
  37. public:
  38. #if REDUCE_SIZE != 0
  39. static bool ReduceStepByStep() { return reduceStepByStep; }
  40. static uint ReduceSize() { return reduceSize; }
  41. uint SetReduceSize(uint rs) {
  42. reduceStepByStep = (reduceSize = rs) ? false : true;
  43. return reduceSize;
  44. }
  45. void Reduce(){ reduce(true); }
  46. #else
  47. static uint ReduceSize() { return 0; }
  48. void Reduce(){ reduce(); }
  49. #endif
  50. bool ReduceDone() const { return reduceDone; }
  51. //Set a value.Give numerator to first argument, denominator to second one.
  52. void SetDouble(double n, double d = 1.0L); // 704
  53. void SetLong(long n, long d = 1L); // 705
  54. void Set(const SLong& n, const SLong& d); // 706
  55. void SetZero() {
  56. num.SetZero(); den = 1.0L; reduceDone = true;
  57. }
  58. //constructors
  59. //These are inline functions since ver.2.30.
  60. SFraction():num(), den(), reduceDone(false){}
  61. SFraction(double n):num(n), den(1.0L), reduceDone(true){}
  62. SFraction(double n, double d):num(n), den(d), reduceDone(false){
  63. DenCheck(); //If d == 1.0 it sets reduceDone = true.
  64. }
  65. SFraction(const char* s):num(), den(), reduceDone(false){
  66. SetString(s);
  67. }
  68. //This provides a method to convert SF*SL to SF*(SL/1.0), not SD*SD.
  69. SFraction(const SLong& n):num(n), den(1.0), reduceDone(true){
  70. RadixCheck();
  71. }
  72. SFraction(const SLong& n, const SLong& d):num(n), den(d), reduceDone(false){
  73. DenCheck(); RadixCheck();
  74. #if REDUCE_SIZE != 0
  75. reduce(false);
  76. #else
  77. reduce();
  78. #endif
  79. }
  80. //copy constructor
  81. SFraction(const SFraction& a) : num(a.num), den(a.den), reduceDone(a.reduceDone){}
  82. virtual ~SFraction(){}
  83. //operator=()
  84. SFraction& operator=(const char *s) { SetString(s); return *this; }
  85. //For a double value its decimal part is omitted,
  86. //e.g. SF = 2.5; ---> 2/1 not 5/2.
  87. SFraction& operator=(double d){
  88. SetDouble(d, 1.0L); // set reduceDone = true; by reduce(false).
  89. return *this;
  90. }
  91. SFraction& operator=(const SFraction& a); // 707
  92. SFraction& operator=(const SLong& a); // 708
  93. //return an irreducible fraction
  94. #if REDUCE_SIZE != 0
  95. SLong Num() { if(!reduceDone) reduce(true); return num; }
  96. SLong Den() { if(!reduceDone) reduce(true); return den; }
  97. #else
  98. SLong Num() { if(!reduceDone) reduce(); return num; }
  99. SLong Den() { if(!reduceDone) reduce(); return den; }
  100. #endif
  101. //return a maybe reducible (Not Reduced) fraction
  102. SLong NumNR() const { return num; }
  103. SLong DenNR() const { return den; }
  104. //sign operator
  105. SFraction operator+() const { return *this; }
  106. SFraction operator-() const; // 709
  107. friend SFraction FFAdd(const SFraction& x, const SFraction& y);//x+y 710
  108. friend SFraction FFSub(const SFraction& x, const SFraction& y);//x-y 711
  109. friend SFraction FFMult(const SFraction& x, const SFraction& y);//x*y 712
  110. friend SFraction FFDiv(const SFraction& x, const SFraction& y); //x/y 713
  111. friend SFraction FsMult(const SFraction& x, ulong s); //x*s 714
  112. friend SFraction FsDiv(const SFraction& x, ulong s); //x/s 715
  113. friend SFraction operator*(const SFraction& f, double d); //f*d 724. operator d*f is defined below as an inline function.
  114. friend SFraction operator/(const SFraction& f, double d); //f/d 725
  115. friend SFraction operator/(double d, const SFraction& f); //d/f 727
  116. SFraction& operator+=(const SFraction& n){ return *this = FFAdd(*this, n); }
  117. SFraction& operator-=(const SFraction& n){ return *this = FFSub(*this, n); }
  118. SFraction& operator*=(const SFraction& n){ return *this = FFMult(*this,n); }
  119. SFraction& operator/=(const SFraction& n){ return *this = FFDiv(*this, n); }
  120. SFraction& operator*=(double d){ return (*this = *this * d); }
  121. SFraction& operator/=(double d){ return (*this = *this / d); }
  122. //return the sign
  123. int Sign(int id = 70) const { return num.Sign(id); }
  124. //change the sign
  125. void ChangeSign(int id = 71){ num.ChangeSign(id); }
  126. enum { BRACKET = 8, MID_CR = 16, END_CR = 32 };
  127. static int lineFormat; // Set by BRACKET | END_CR | MID_CR. Set "BRACKET" in default
  128. static void SetFormat(int fmt); // The format of Num() and Den() obey that of SLong.
  129. static long ioCount;
  130. //output functions
  131. long Put(int fmt = BRACKET); //740
  132. long Puts(int fmt = BRACKET){ return Put(fmt|END_CR); }
  133. };
  134. inline SFraction operator+(const SFraction& m, const SFraction& n) {// m+n
  135. return FFAdd(m, n);
  136. }
  137. inline SFraction operator-(const SFraction& m, const SFraction& n){// m-n
  138. return FFSub(m, n);
  139. }
  140. inline SFraction operator*(const SFraction& m, const SFraction& n){// m*n
  141. return FFMult(m, n);
  142. }
  143. inline SFraction operator/(const SFraction& m, const SFraction& n){// m/n
  144. return FFDiv(m, n);
  145. }
  146. inline void SFraction::RadixCheck() const{
  147. if( (num.Type() & num.BIN_RDX) || (den.Type() & num.BIN_RDX) )
  148. num.SetError(num.RADIX_ERR, "SF", 72);
  149. }
  150. inline SFraction operator*(double d, const SFraction& f){ return f*d; } //d*f
  151. // mathematical functions ID
  152. //compare absolute values, return 1 if |m|>|n|, 0 if |m|==|n|, -1 if |m|<|n|
  153. int FFCompare(const SFraction& m, const SFraction& n); //7001
  154. SFraction Fabs(const SFraction& x); //7002
  155. //Definition of relational operators
  156. bool operator==(const SFraction& m, const SFraction& n); // 7003
  157. inline bool operator>(const SFraction& m, const SFraction& n){
  158. if(m.Sign(74) != n.Sign(74)) return m.Sign() > n.Sign();
  159. return (FFCompare(m, n) * m.Sign()) > 0;
  160. }
  161. inline bool operator<(const SFraction& m, const SFraction& n){
  162. if(m.Sign(75) != n.Sign(75)) return m.Sign() < n.Sign();
  163. return (FFCompare(m, n) * m.Sign()) < 0;
  164. }
  165. inline bool operator!=(const SFraction& m, const SFraction& n){
  166. return !(m == n);
  167. }
  168. inline bool operator>=(const SFraction& m, const SFraction& n){
  169. if(m.Sign(77) != n.Sign(77)) return m.Sign() > n.Sign();
  170. return (FFCompare(m, n)*m.Sign()) >= 0;
  171. }
  172. inline bool operator<=(const SFraction& m, const SFraction& n){
  173. if(m.Sign(78) != n.Sign(78)) return m.Sign() < n.Sign();
  174. return (FFCompare(m, n)*m.Sign()) <= 0;
  175. }
  176. inline SLong& SLong::operator=(const SFraction& sf){
  177. return *this = sf.NumNR()/sf.DenNR();
  178. }
  179. ostream& operator<<(ostream& os, SFraction& sf); // 7004SS not "const" object due to "reduce(true);" since ver. 2.21
  180. #endif // S_FRACTION_H

sfract.h : last modifiled at 2017/10/23 10:20:49(7,769 bytes)
created at 2016/04/11 11:18:59
The creation time of this html file is 2017/10/23 10:29:22 (Mon Oct 23 10:29:22 2017).