- /* sfract.h by K.Tsuru */
- // file ID = 700 DRADIX
- /****************************************
- SFraction class using SLong arithmetric
- See SRational class
- ******************************************/
- /***********************************************************************
- About the timing of reduction.
- 1)#define REDUCE_SIZE 0 // below
- If it would be done every time after an operation, it takes many times.
- 2)#define REDUCE_SIZE 1 // below
- Then the ruduction is called when
- 1.maximum figure of numerator and denominator exceeds a threshold value.
- 2.output function is called.
- 3."Reduce()" is called.
-
- Speed depends on the sytem FPU and OS. On my machine 1) is faster about twice.
- Please try/test on your system.
- ************************************************************************/
- #ifndef S_FRACTION_H
- #define S_FRACTION_H
- #define REDUCE_SIZE 0 // reduceSize = 0; reduceStepByStep = true; Knuth's method is used.
- class SFraction {
- SLong num, den; //"num" has the sign and "den" is always positive.
- bool reduceDone;
- #if REDUCE_SIZE != 0
- static uint reduceSize; //a threshold value for reduction
- static bool reduceStepByStep; // Knuth's method is used or not.
- void reduce(bool must); //701 do reduce
- #endif
- void reduce(); //701 do reduce
- void SetString(const char *s); // 702
- SFraction& operator=(const SDouble& a); // has no body
- SFraction& operator=(const SDecimal& a); // has no body
- SFraction& operator=(const SInteger& a); // has no body
- void DenCheck(); // 703
- void RadixCheck() const; // inline function
- public:
- #if REDUCE_SIZE != 0
- static bool ReduceStepByStep() { return reduceStepByStep; }
- static uint ReduceSize() { return reduceSize; }
- uint SetReduceSize(uint rs) {
- reduceStepByStep = (reduceSize = rs) ? false : true;
- return reduceSize;
- }
- void Reduce(){ reduce(true); }
- #else
- static uint ReduceSize() { return 0; }
- void Reduce(){ reduce(); }
- #endif
- bool ReduceDone() const { return reduceDone; }
- //Set a value.Give numerator to first argument, denominator to second one.
- void SetDouble(double n, double d = 1.0L); // 704
- void SetLong(long n, long d = 1L); // 705
- void Set(const SLong& n, const SLong& d); // 706
- void SetZero() {
- num.SetZero(); den = 1.0L; reduceDone = true;
- }
- //constructors
- //These are inline functions since ver.2.30.
- SFraction():num(), den(), reduceDone(false){}
- SFraction(double n):num(n), den(1.0L), reduceDone(true){}
- SFraction(double n, double d):num(n), den(d), reduceDone(false){
- DenCheck(); //If d == 1.0 it sets reduceDone = true.
- }
- SFraction(const char* s):num(), den(), reduceDone(false){
- SetString(s);
- }
- //This provides a method to convert SF*SL to SF*(SL/1.0), not SD*SD.
- SFraction(const SLong& n):num(n), den(1.0), reduceDone(true){
- RadixCheck();
- }
- SFraction(const SLong& n, const SLong& d):num(n), den(d), reduceDone(false){
- DenCheck(); RadixCheck();
- #if REDUCE_SIZE != 0
- reduce(false);
- #else
- reduce();
- #endif
- }
- //copy constructor
- SFraction(const SFraction& a) : num(a.num), den(a.den), reduceDone(a.reduceDone){}
- virtual ~SFraction(){}
- //operator=()
- SFraction& operator=(const char *s) { SetString(s); return *this; }
- //For a double value its decimal part is omitted,
- //e.g. SF = 2.5; ---> 2/1 not 5/2.
- SFraction& operator=(double d){
- SetDouble(d, 1.0L); // set reduceDone = true; by reduce(false).
- return *this;
- }
- SFraction& operator=(const SFraction& a); // 707
- SFraction& operator=(const SLong& a); // 708
- //return an irreducible fraction
- #if REDUCE_SIZE != 0
- SLong Num() { if(!reduceDone) reduce(true); return num; }
- SLong Den() { if(!reduceDone) reduce(true); return den; }
- #else
- SLong Num() { if(!reduceDone) reduce(); return num; }
- SLong Den() { if(!reduceDone) reduce(); return den; }
- #endif
- //return a maybe reducible (Not Reduced) fraction
- SLong NumNR() const { return num; }
- SLong DenNR() const { return den; }
-
- //sign operator
- SFraction operator+() const { return *this; }
- SFraction operator-() const; // 709
- friend SFraction FFAdd(const SFraction& x, const SFraction& y);//x+y 710
- friend SFraction FFSub(const SFraction& x, const SFraction& y);//x-y 711
- friend SFraction FFMult(const SFraction& x, const SFraction& y);//x*y 712
- friend SFraction FFDiv(const SFraction& x, const SFraction& y); //x/y 713
- friend SFraction FsMult(const SFraction& x, ulong s); //x*s 714
- friend SFraction FsDiv(const SFraction& x, ulong s); //x/s 715
- friend SFraction operator*(const SFraction& f, double d); //f*d 724. operator d*f is defined below as an inline function.
- friend SFraction operator/(const SFraction& f, double d); //f/d 725
- friend SFraction operator/(double d, const SFraction& f); //d/f 727
-
- SFraction& operator+=(const SFraction& n){ return *this = FFAdd(*this, n); }
- SFraction& operator-=(const SFraction& n){ return *this = FFSub(*this, n); }
- SFraction& operator*=(const SFraction& n){ return *this = FFMult(*this,n); }
- SFraction& operator/=(const SFraction& n){ return *this = FFDiv(*this, n); }
- SFraction& operator*=(double d){ return (*this = *this * d); }
- SFraction& operator/=(double d){ return (*this = *this / d); }
- //return the sign
- int Sign(int id = 70) const { return num.Sign(id); }
- //change the sign
- void ChangeSign(int id = 71){ num.ChangeSign(id); }
-
- enum { BRACKET = 8, MID_CR = 16, END_CR = 32 };
- static int lineFormat; // Set by BRACKET | END_CR | MID_CR. Set "BRACKET" in default
- static void SetFormat(int fmt); // The format of Num() and Den() obey that of SLong.
- static long ioCount;
- //output functions
- long Put(int fmt = BRACKET); //740
- long Puts(int fmt = BRACKET){ return Put(fmt|END_CR); }
- };
- inline SFraction operator+(const SFraction& m, const SFraction& n) {// m+n
- return FFAdd(m, n);
- }
- inline SFraction operator-(const SFraction& m, const SFraction& n){// m-n
- return FFSub(m, n);
- }
- inline SFraction operator*(const SFraction& m, const SFraction& n){// m*n
- return FFMult(m, n);
- }
- inline SFraction operator/(const SFraction& m, const SFraction& n){// m/n
- return FFDiv(m, n);
- }
- inline void SFraction::RadixCheck() const{
- if( (num.Type() & num.BIN_RDX) || (den.Type() & num.BIN_RDX) )
- num.SetError(num.RADIX_ERR, "SF", 72);
- }
- inline SFraction operator*(double d, const SFraction& f){ return f*d; } //d*f
-
- // mathematical functions ID
- //compare absolute values, return 1 if |m|>|n|, 0 if |m|==|n|, -1 if |m|<|n|
- int FFCompare(const SFraction& m, const SFraction& n); //7001
- SFraction Fabs(const SFraction& x); //7002
- //Definition of relational operators
- bool operator==(const SFraction& m, const SFraction& n); // 7003
- inline bool operator>(const SFraction& m, const SFraction& n){
- if(m.Sign(74) != n.Sign(74)) return m.Sign() > n.Sign();
- return (FFCompare(m, n) * m.Sign()) > 0;
- }
- inline bool operator<(const SFraction& m, const SFraction& n){
- if(m.Sign(75) != n.Sign(75)) return m.Sign() < n.Sign();
- return (FFCompare(m, n) * m.Sign()) < 0;
- }
- inline bool operator!=(const SFraction& m, const SFraction& n){
- return !(m == n);
- }
- inline bool operator>=(const SFraction& m, const SFraction& n){
- if(m.Sign(77) != n.Sign(77)) return m.Sign() > n.Sign();
- return (FFCompare(m, n)*m.Sign()) >= 0;
- }
- inline bool operator<=(const SFraction& m, const SFraction& n){
- if(m.Sign(78) != n.Sign(78)) return m.Sign() < n.Sign();
- return (FFCompare(m, n)*m.Sign()) <= 0;
- }
- inline SLong& SLong::operator=(const SFraction& sf){
- return *this = sf.NumNR()/sf.DenNR();
- }
- ostream& operator<<(ostream& os, SFraction& sf); // 7004SS not "const" object due to "reduce(true);" since ver. 2.21
- #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).