トップページに戻る    次のC#のサンプルへ    前のC#のサンプルへ

9-2 仮分数クラス

C#のサンプル

割り算での誤差防止のために作成した仮分数クラスを扱うクラスです。
真分数も扱いますが :-)


ソース

using System;

internal class CKabunSuu
{
    private long mBunshi; //分子
    private long mBunbo; //分母

    //コンストラクタ (値指定)
    internal CKabunSuu(long pBunshi, long pBunbo)
    {
        mBunshi = pBunshi;
        mBunbo = pBunbo;
    }

    //コンストラクタ (インスタンス指定)
    internal CKabunSuu(CKabunSuu pIns)
    {
        mBunshi = pIns.mBunshi;
        mBunbo = pIns.mBunbo;
    }

    //加算用メソッド (値指定)
    internal void Add(long pVal)
    {
        //通分してから、加算
        mBunshi += pVal * mBunbo;
        Yakubun();
    }

    //加算用メソッド (インスタンス指定)
    internal void Add(CKabunSuu pIns)
    {
        long SavedBunbo = mBunbo; //通分する前の分母

        //通分してから、加算
        mBunbo *= pIns.mBunbo;
        mBunshi = this.mBunshi * pIns.mBunbo + pIns.mBunshi * SavedBunbo;
        Yakubun();
    }

    //減算用メソッド (値指定)
    internal void Subtract(long pVal)
    {
        Add(-pVal);
    }

    //減算用メソッド (インスタンス指定)
    internal void Subtract(CKabunSuu pIns)
    {
        Add(new CKabunSuu(-pIns.mBunshi, pIns.mBunbo));
    }

    //乗算用メソッド (値指定)
    internal void Prod(long pVal)
    {
        mBunshi *= pVal;
        Yakubun();
    }

    //乗算用メソッド (インスタンス指定)
    internal void Prod(CKabunSuu pIns)
    {
        this.mBunshi *= pIns.mBunshi;
        this.mBunbo *= pIns.mBunbo;
        Yakubun();
    }

    //除算用メソッド (値指定)
    internal void Div(long pVal)
    {
        mBunbo *= pVal;
        Yakubun();
    }

    //除算用メソッド (インスタンス指定)
    internal void Div(CKabunSuu pIns)
    {
        this.mBunshi *= pIns.mBunbo;
        this.mBunbo *= pIns.mBunshi;
        Yakubun();
    }

    //約分
    private void Yakubun()
    {
        if (mBunshi == 0) return;

        long GCD; //最大公約数
        GCD = DeriveGCD(mBunshi, mBunbo);
        if (GCD == 1) return;
        mBunshi /= GCD;
        mBunbo /= GCD;
    }

    //ユークリッドの互除法で2数の最大公約数を求める
    private long DeriveGCD(long pVal1, long pVal2)
    {
        pVal1 = Math.Abs(pVal1);
        pVal2 = Math.Abs(pVal2);

        long WarareruKazu = Math.Max(pVal1, pVal2);
        long WaruKazu = Math.Min(pVal1, pVal2);

        while (true) {
            long Amari = WarareruKazu % WaruKazu;
            if (Amari == 0) return WaruKazu;
            WarareruKazu = WaruKazu;
            WaruKazu = Amari;
        }
    }

    //分数の値を返す
    internal decimal DecimalValue
    {
        get { return (decimal)mBunshi / mBunbo; }
    }
}

class Program
{
    static void Main()
    {
        var InsTest = new CKabunSuu(1, 1);
        InsTest.Div(new CKabunSuu(2, 1));
        InsTest.Div(new CKabunSuu(3, 1));
        InsTest.Prod(new CKabunSuu(456, 1));
        InsTest.Add(new CKabunSuu(7, 1));
        InsTest.Add(new CKabunSuu(8, 1));
        InsTest.Add(new CKabunSuu(9, 1));
        Console.WriteLine(InsTest.DecimalValue);
    }
}