提供了各种运算符并实现了IComparable接口,可以像使用系统自带数据类型一样方便地使用分数.

提供将字符串转化为分数以及将分数转化为小数的方法.

PS:求小数转化为分数的算法~~~

//Version 0.9.7
using System;
using IntType = System.Int64;    //整形数和小数的类型可根据需要定义
using RealType = System.Double;
namespace Takamachi660.Math
{
    
public class FractionException : System.Exception 
    
{
        
public FractionException(string msg) : base(msg) { }
        
public FractionException() : base() { }
    }

    [Serializable]
    
public struct Fraction : IComparable<Fraction>, IComparable
    
{
        
private IntType iNum, iDen; //分子/分母,私有字段
        public IntType iNumerator get return iNum; } }   //外部通过只读属性获取分子和分母的值
        public IntType iDenominator get return iDen; } }
        
public Fraction(Fraction value)
        
{
            
this.iNum = value.iNum;
            
this.iDen = value.iDen;
            Simplify();
        }

        
public Fraction(IntType iNum, IntType iDen)
        
{
            
this.iNum = iNum;
            
this.iDen = iDen;
            Simplify();
        }

        
public Fraction(string s)
        
{
            
if (string.IsNullOrEmpty(s))
            
{
                
this.iNum = 0;
                
this.iDen = 1;
            }

            
else
            
{
                
this = ConvertFromString(s);
            }

        }

        
private void DenZeroCheck()
        
{
            
if (this.iDen == 0)
            
{
                
throw new FractionException("分母为\"0\"");
            }

        }

        
private Fraction Simplify()
        
{
            DenZeroCheck();
            
if (iDen < 0)
            
{
                iDen 
*= -1;
                iNum 
*= -1;
            }

            IntType cm 
= CommonDivisor(Math.Abs(iNum), iDen);
            
if (cm == 1)
                
return this;
            iNum 
/= cm;
            iDen 
/= cm;
            
return this;
        }

        
public override int GetHashCode()
        
{
            Simplify();
            
return ((double)iNum / (double)iDen).GetHashCode();
        }

        
public override bool Equals(object obj)
        
{
            
if (obj is Fraction)
                
return iNum == ((Fraction)obj).iNum && iDen == ((Fraction)obj).iDen;
            
return false;
        }

        
public override string ToString()
        
{
            
string strOutput;
            Simplify();
            
if (iDen != 1)
                strOutput 
= string.Format(@"{0}/{1}", iNum, iDen);
            
else
                strOutput 
= string.Format(@"{0}", iNum);
            
return strOutput;
        }

        
public RealType ToReal()
        
{
            
return (RealType)this.iNum / (RealType)this.iDen;
        }

        
private static IntType CommonDivisor(IntType m, IntType n)
        
{
            m 
= m < 0 ? -m : m;
            n 
= n < 0 ? -n : n;
            IntType temp;
            
if (n < m)
            
{
                temp 
= n;
                n 
= m;
                m 
= temp;
            }

            
while (m != 0)
            
{
                temp 
= n % m;
                n 
= m;
                m 
= temp;
            }

            
return n;
        }

        
private static IntType CommonMultiple(IntType m, IntType n)
        
{
            IntType p 
= Math.Abs(n * m);
            n 
= CommonDivisor(m, n);
            
return p / n;
        }

        
public void SetValue(IntType iNum, IntType iDen)
        
{
            
this.iNum = iNum;
            
this.iDen = iDen;
            Simplify();
        }

        
public void SetValue(string s)
        
{
            
this = ConvertFromString(s);
        }

        
public static Fraction ConvertFromString(string s)
        
{
            Fraction output;
            
if (!Fraction.TryParse(s, out output))
            
{
                
throw new FractionException(string.Format("无法将字符串\"{0}\"转化为分数", s));
            }

            
return output;
        }

        
public static bool TryParse(string s, out Fraction result)  //将字符串转化为分数
        {
            s.Trim();
            
if (s.IndexOf(@"/"< 0)
            
{
                result.iDen 
= 1;
                
if (!IntType.TryParse(s, out result.iNum))
                
{
                    result.iNum 
= 0;
                    
return false;
                }

                
return true;
            }

            
if (s.IndexOf(@"/"!= s.LastIndexOf(@"/"))
            
{
                result.iNum 
= 0;
                result.iDen 
= 1;
                
return false;
            }

            
string[] temp = s.Split('/');
            
if (!IntType.TryParse(temp[0], out result.iNum) || !IntType.TryParse(temp[1], out result.iDen))
            
{
                result.iNum 
= 0;
                result.iDen 
= 1;
                
return false;
            }

            result.Simplify();
            
return true;
        }

        
//重载比较运算符
        public static bool operator ==(Fraction a, Fraction b)
        
{
            
return a.GetHashCode() == b.GetHashCode();
        }

        
public static bool operator ==(IntType a, Fraction b)
        
{
            
//return new Fraction(a, 1) == b;
            return a == b.ToReal();
        }

        
public static bool operator ==(Fraction a, IntType b)
        
{
            
return b == a;
        }

        
public static bool operator ==(RealType a, Fraction b)
        
{
            
return a == b.ToReal();
        }

        
public static bool operator ==(Fraction a, RealType b)
        
{
            
return b == a;
        }

        
public static bool operator !=(Fraction a, Fraction b)
        
{
            
return !(a == b);
        }

        
public static bool operator !=(IntType a, Fraction b)
        
{
            
return !(a == b);
        }

        
public static bool operator !=(Fraction a, IntType b)
        
{
            
return !(a == b);
        }

        
public static bool operator !=(RealType a, Fraction b)
        
{
            
return !(a == b);
        }

        
public static bool operator !=(Fraction a, RealType b)
        
{
            
return !(a == b);
        }

        
public static bool operator >(Fraction a, Fraction b)
        
{
            
if (a.GetHashCode() == b.GetHashCode())
                
return false;
            IntType cm 
= CommonMultiple(a.iDen, b.iDen);//分母的最小公倍数
            IntType an = a.iNum * (cm / a.iDen);//a的分子
            IntType bn = b.iNum * (cm / b.iDen);//b的分子
            return an > bn;
        }

        
public static bool operator >(IntType a, Fraction b)
        
{
            
//return new Fraction(a, 1) > b;
            return a > b.ToReal();
        }

        
public static bool operator >(Fraction a, IntType b)
        
{
            
//return a > new Fraction(b, 1);
            return a.ToReal() > b;
        }

        
public static bool operator >(RealType a, Fraction b)
        
{
            
return a > b.ToReal();
        }

        
public static bool operator >(Fraction a, RealType b)
        
{
            
return a.ToReal() > b;
        }

        
public static bool operator <(Fraction a, Fraction b)
        
{
            
if (a.GetHashCode() == b.GetHashCode())
                
return false;
            IntType cm 
= CommonMultiple(a.iDen, b.iDen);//分母的最小公倍数
            IntType an = a.iNum * (cm / a.iDen);//a的分子
            IntType bn = b.iNum * (cm / b.iDen);//b的分子
            return an < bn;
        }

        
public static bool operator <(IntType a, Fraction b)
        
{
            
//return new Fraction(a, 1) < b;
            return a < b.ToReal();
        }

        
public static bool operator <(Fraction a, IntType b)
        
{
            
//return a < new Fraction(b, 1);
            return a.ToReal() < b;
        }

        
public static bool operator <(RealType a, Fraction b)
        
{
            
return a < b.ToReal();
        }

        
public static bool operator <(Fraction a, RealType b)
        
{
            
return a.ToReal() < b;
        }

        
public static bool operator >=(Fraction a, Fraction b)
        
{
            
if (a.GetHashCode() == b.GetHashCode())
                
return true;
            IntType cm 
= CommonMultiple(a.iDen, b.iDen);//分母的最小公倍数
            IntType an = a.iNum * (cm / a.iDen);//a的分子
            IntType bn = b.iNum * (cm / b.iDen);//b的分子
            return an >= bn;
        }

        
public static bool operator >=(IntType a, Fraction b)
        
{
            
//return new Fraction(a, 1) >= b;
            return a >= b.ToReal();
        }

        
public static bool operator >=(Fraction a, IntType b)
        
{
            
//return a >= new Fraction(b, 1);
            return a.ToReal() >= b;
        }

        
public static bool operator >=(RealType a, Fraction b)
        
{
            
return a >= b.ToReal();
        }

        
public static bool operator >=(Fraction a, RealType b)
        
{
            
return a.ToReal() >= b;
        }

        
public static bool operator <=(Fraction a, Fraction b)
        
{
            
if (a.GetHashCode() == b.GetHashCode())
                
return true;
            IntType cm 
= CommonMultiple(a.iDen, b.iDen);//分母的最小公倍数
            IntType an = a.iNum * (cm / a.iDen);//a的分子
            IntType bn = b.iNum * (cm / b.iDen);//b的分子
            return an <= bn;
        }

        
public static bool operator <=(IntType a, Fraction b)
        
{
            
//return new Fraction(a, 1) <= b;
            return a <= b.ToReal();
        }

        
public static bool operator <=(Fraction a, IntType b)
        
{
            
//return a <= new Fraction(b, 1);
            return a.ToReal() <= b;
        }

        
public static bool operator <=(RealType a, Fraction b)
        
{
            
return a <= b.ToReal();
        }

        
public static bool operator <=(Fraction a, RealType b)
        
{
            
return a.ToReal() <= b;
        }

        
//重载四则运算符
        public static Fraction operator +(Fraction a, Fraction b)
        
{
            a.DenZeroCheck();
            b.DenZeroCheck();
            IntType cm 
= CommonMultiple(a.iDen, b.iDen);//分母的最小公倍数
            IntType an = a.iNum * (cm / a.iDen);//a的分子
            IntType bn = b.iNum * (cm / b.iDen);//b的分子
            return new Fraction(an + bn, cm);
        }

        
public static Fraction operator +(IntType a, Fraction b)
        
{
            
return (new Fraction(a, 1+ b);
        }

        
public static Fraction operator +(Fraction a, IntType b)
        
{
            
return b + a;
        }

        
public static Fraction operator -(Fraction obj)
        
{
            obj.iNum 
*= -1;
            
return obj;
        }

        
public static Fraction operator -(Fraction a, Fraction b)
        
{
            
return a + (-b);
        }

        
public static Fraction operator -(IntType a, Fraction b)
        
{
            
return a + (-b);
        }

        
public static Fraction operator -(Fraction a, IntType b)
        
{
            
return a + (-b);
        }

        
public static Fraction operator *(Fraction a, Fraction b)
        
{
            
return new Fraction(a.iNum * b.iNum, a.iDen * b.iDen);
        }

        
public static Fraction operator *(IntType a, Fraction b)
        
{
            
return new Fraction(a, 1* b;
        }

        
public static Fraction operator *(Fraction a, IntType b)
        
{
            
return b * a;
        }

        
public static Fraction operator !(Fraction obj)//求倒数
        {
            
if (obj == 0)
                
throw new FractionException("无法求\"0\"的倒数");
            
return new Fraction(obj.iDen, obj.iNum);//交换分子与分母
        }

        
public static Fraction operator /(Fraction a, Fraction b)
        
{
            
if (b == 0)
                
throw new FractionException("\"0\"作为除数");
            
return a * !b;
        }

        
public static Fraction operator /(IntType a, Fraction b)
        
{
            
if (b == 0)
                
throw new FractionException("\"0\"作为除数");
            
return a * !b;
        }

        
public static Fraction operator /(Fraction a, IntType b)
        
{
            
if (b == 0)
                
throw new FractionException("\"0\"作为除数");
            a.iDen 
*= b;
            
return a.Simplify();
        }

        
public static Fraction operator |(Fraction a, Fraction b)//求最大公约数
        {
            
return new Fraction(CommonDivisor(a.iNum, b.iNum), CommonMultiple(a.iDen, b.iDen));
        }

        
public static Fraction operator &(Fraction a, Fraction b)//求最小公倍数
        {
            
return new Fraction(CommonMultiple(a.iNum, b.iNum), CommonDivisor(a.iDen, b.iDen));
        }

        
int IComparable<Fraction>.CompareTo(Fraction other)
        
{
            Fraction dis 
= this - other;
            
return (int)(dis.iNum / dis.iDen);
        }

        
int IComparable.CompareTo(object other)
        
{
            
if (other is IntType)
            
{
                
return (int)((this - (IntType)other).ToReal());
            }

            
else if (other is Fraction)
            
{
                
return (this as IComparable<Fraction>).CompareTo((Fraction)other);
            }

            
else if (other is RealType)
            
{
                
return (int)(this.ToReal() - (RealType)other);
            }

            
else
                
return 0;
        }

    }

}

 

posted on 2009-08-05 11:04  高町⑥⑥○  阅读(351)  评论(0编辑  收藏  举报