I'm working on modernizing Rosetta Code's infrastructure. Starting with communications. Please accept this time-limited open invite to RC's Slack.. --Michael Mol (talk) 20:59, 30 May 2020 (UTC)

# Arithmetic/Rational/C sharp

Arithmetic/Rational/C sharp is part of Rational Arithmetic. You may find other members of Rational Arithmetic at Category:Rational Arithmetic.
`using System; struct Fraction : IEquatable<Fraction>, IComparable<Fraction>{    public readonly long Num;    public readonly long Denom;     public Fraction(long num, long denom)    {        if (num == 0)        {            denom = 1;        }        else if (denom == 0)        {            throw new ArgumentException("Denominator may not be zero", "denom");        }        else if (denom < 0)        {            num = -num;            denom = -denom;        }         long d = GCD(num, denom);        this.Num = num / d;        this.Denom = denom / d;    }     private static long GCD(long x, long y)    {        return y == 0 ? x : GCD(y, x % y);    }     private static long LCM(long x, long y)    {        return x / GCD(x, y) * y;    }     public Fraction Abs()    {        return new Fraction(Math.Abs(Num), Denom);    }     public Fraction Reciprocal()    {        return new Fraction(Denom, Num);    }     #region Conversion Operators     public static implicit operator Fraction(long i)    {        return new Fraction(i, 1);    }     public static explicit operator double(Fraction f)    {        return f.Num == 0 ? 0 : (double)f.Num / f.Denom;    }     #endregion     #region Arithmetic Operators     public static Fraction operator -(Fraction f)    {        return new Fraction(-f.Num, f.Denom);    }     public static Fraction operator +(Fraction a, Fraction b)    {        long m = LCM(a.Denom, b.Denom);        long na = a.Num * m / a.Denom;        long nb = b.Num * m / b.Denom;        return new Fraction(na + nb, m);    }     public static Fraction operator -(Fraction a, Fraction b)    {        return a + (-b);    }     public static Fraction operator *(Fraction a, Fraction b)    {        return new Fraction(a.Num * b.Num, a.Denom * b.Denom);    }     public static Fraction operator /(Fraction a, Fraction b)    {        return a * b.Reciprocal();    }     public static Fraction operator %(Fraction a, Fraction b)    {        long l = a.Num * b.Denom, r = a.Denom * b.Num;        long n = l / r;        return new Fraction(l - n * r, a.Denom * b.Denom);    }     #endregion     #region Comparison Operators     public static bool operator ==(Fraction a, Fraction b)    {        return a.Num == b.Num && a.Denom == b.Denom;    }     public static bool operator !=(Fraction a, Fraction b)    {        return a.Num != b.Num || a.Denom != b.Denom;    }     public static bool operator <(Fraction a, Fraction b)    {        return (a.Num * b.Denom) < (a.Denom * b.Num);    }     public static bool operator >(Fraction a, Fraction b)    {        return (a.Num * b.Denom) > (a.Denom * b.Num);    }     public static bool operator <=(Fraction a, Fraction b)    {        return !(a > b);    }     public static bool operator >=(Fraction a, Fraction b)    {        return !(a < b);    }     #endregion     #region Object Members     public override bool Equals(object obj)    {        if (obj is Fraction)            return ((Fraction)obj) == this;        else            return false;    }     public override int GetHashCode()    {        return Num.GetHashCode() ^ Denom.GetHashCode();    }     public override string ToString()    {        return Num.ToString() + "/" + Denom.ToString();    }     #endregion     #region IEquatable<Fraction> Members     public bool Equals(Fraction other)    {        return other == this;    }     #endregion     #region IComparable<Fraction> Members     public int CompareTo(Fraction other)    {        return (this.Num * other.Denom).CompareTo(this.Denom * other.Num);    }     #endregion}`

Test program:

`using System; static class Program{    static void Main(string[] args)    {        int max = 1 << 19;        for (int candidate = 2; candidate < max; candidate++)        {            Fraction sum = new Fraction(1, candidate);            int max2 = (int)Math.Sqrt(candidate);            for (int factor = 2; factor <= max2; factor++)            {                if (candidate % factor == 0)                {                    sum += new Fraction(1, factor);                    sum += new Fraction(1, candidate / factor);                }            }             if (sum == 1)                Console.WriteLine("{0} is perfect", candidate);        }    }}`
Output:
```6 is perfect
28 is perfect
496 is perfect
8128 is perfect```