3
1

More than 5 years have passed since last update.

C#でも分数class

Posted at

前の記事で、C++で分数classを作ったのですが(https://qiita.com/HitsujiRere/items/43a4b53c64b8eec3b7bd )、C#でも書いてみようと思ったので書きました

前記事(C++編)の参考
- http://blog.livedoor.jp/add20/archives/2285655.html
- http://www002.upp.so-net.ne.jp/ys_oota/effec/chapter4.htm

コードは下記(# コード)

内容

コメントを書き忘れたのですが、C++の記事とほぼ同じですし、大体はコードを読んでもらえるとわかると思います

numerは分子denomは分母を表しています

あと、ToString()や四則演算,等号不等号,キャストを実装してありますので、使い物にはなると思います

感想

C++やC#、どちらも良いところがあるなと感じた

C++ではlong→Fractionのキャストを書かなくても、インスタンスから自動的に変換してくれる(みたいだ

C#ではメソッドなどがかなり書きやすいと感じた(慣れもあるかもしれない

コード

コードはこちら
VS19で書いたのでnamespaceがありますが、そこを適当に変えるor削除するなどお願います

using System;

namespace Fraction_cs
{
    class Fraction
    {
        public long numer { get; private set; }
        public long denom { get; private set; }

        public Fraction(long numer = 0)
        {
            this.numer = numer;
            this.denom = 1;
        }
        public Fraction(long numer, long denom)
        {
            this.numer = numer;
            this.denom = denom;
            Normal();
        }
        public Fraction(Fraction b)
        {
            this.numer = b.numer;
            this.denom = b.denom;
        }

        static void Swap<T>(ref T a, ref T b)
        {
            var tmp = a;
            a = b;
            b = tmp;
        }
        static long GCD(long a, long b)
        {
            a = Math.Abs(a);
            b = Math.Abs(b);

            if (a < b) Swap(ref a, ref b);

            if (a == 1) return b;

            var tmp = a;
            while (b != 0)
            {
                tmp = b;
                b = a % b;
                a = tmp;
            }

            return tmp;
        }
        static long LCM(long a, long b)
        {
            a = Math.Abs(a);
            b = Math.Abs(b);
            if (a > b) Swap(ref a, ref b);

            if (a == 1) return b;

            var tmp = a;
            while (tmp % b != 0)
            {
                tmp += a;
            }
            return tmp;
        }
        void Normal()
        {
            var gcd = GCD(numer, denom);

            numer /= gcd;
            denom /= gcd;

            if (denom < 0)
            {
                numer *= -1;
                denom *= -1;
            }
        }

        public override string ToString()
        {
            if (denom == 1)
            {
                return numer.ToString();
            }
            else
            {
                return numer + "/" + denom;
            }
        }
        public override bool Equals(object b)
        {
            if (b is Fraction b2 &&
                this.numer == b2.numer &&
                this.denom == b2.denom)
            {
                return true;
            }

            return false;
        }
        public static long Compare(Fraction a, Fraction b)
        {
            var lcm = LCM(a.denom, b.denom);

            return (lcm / a.denom) * a.numer - (lcm / b.denom) * b.numer;
        }

        public static bool operator ==(Fraction a, Fraction b)
        {
            return a.Equals(b);
        }
        public static bool operator !=(Fraction a, Fraction b)
        {
            return !a.Equals(b);
        }
        public static bool operator >=(Fraction a, Fraction b)
        {
            return Compare(a, b) >= 0;
        }
        public static bool operator >(Fraction a, Fraction b)
        {
            return Compare(a, b) > 0;
        }
        public static bool operator <=(Fraction a, Fraction b)
        {
            return Compare(a, b) <= 0;
        }
        public static bool operator <(Fraction a, Fraction b)
        {
            return Compare(a, b) < 0;
        }

        public static Fraction operator +(Fraction a, Fraction b)
        {
            var lcm = LCM(a.denom, b.denom);
            var numer = a.numer * (lcm / a.denom) + b.numer * (lcm / b.denom);

            return new Fraction(numer, lcm);
        }
        public static Fraction operator -(Fraction a, Fraction b)
        {
            var lcm = LCM(a.denom, b.denom);
            var numer = a.numer * (lcm / a.denom) - b.numer * (lcm / b.denom);

            return new Fraction(numer, lcm);
        }
        public static Fraction operator *(Fraction a, Fraction b)
        {
            var gcd = GCD(a.numer, b.denom);
            var numer = a.numer / gcd;
            var denom = b.denom / gcd;

            gcd = GCD(b.numer, a.denom);
            numer *= b.numer / gcd;
            denom *= a.denom / gcd;

            return new Fraction(numer, denom);
        }
        public static Fraction operator /(Fraction a, Fraction b)
        {
            var gcd = GCD(a.numer, b.numer);
            var numer = a.numer / gcd;
            var denom = b.numer / gcd;

            gcd = GCD(b.denom, a.denom);
            numer *= b.denom / gcd;
            denom *= a.denom / gcd;

            return new Fraction(numer, denom);
        }

        public static Fraction operator +(Fraction a)
        {
            return new Fraction(a);
        }
        public static Fraction operator -(Fraction a)
        {
            var b = new Fraction(a);
            b.numer *= -1;
            return b;
        }

        public static Fraction operator ++(Fraction a)
        {
            a.numer++;
            a.Normal();
            return new Fraction(a);
        }
        public static Fraction operator --(Fraction a)
        {
            a.numer--;
            a.Normal();
            return new Fraction(a);
        }

        public static implicit operator Fraction(long a)
        {
            return new Fraction(a);
        }
        public static explicit operator double(Fraction a)
        {
            return (double)a.numer / (double)a.denom;
        }
    }
}
3
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
1