読者です 読者をやめる 読者になる 読者になる

雨谷の日和

過去12年で1,600を超えるアニメの第1話だけは見続けた僕のお勧めアニメがハズレなはずがない

分数での掃き出し法による行列式計算10

足し算・引き算の前提処理として、約分と通分の処理を実装しておきます。
まずは約分から。
ソースコード

  public Fraction reduce(){
    if(isZero() || isInfinity())return this;
    long gcd = MathUtil.gcd(numerator, denominator);
    if(gcd == 1)return this;
    return new Fraction(numerator / gcd, denominator / gcd);
  }

自分自身が0か無限大のときは、約分の必要が無いのでそのまま自分自身(this)を返します。
0でも無限大でも無い場合は、分子(numerator)と分母(denominator)の最大公約数(gcd)を求め、それが1かどうかを確認します。
gcd が1だったら、約分できないのでやはり自分自身をそのまま返します。
それ以外の場合、gcd で分子と分母を割った結果で新しくFraction のインスタンスを作成して返します。
さて、これを実際に使ってみましょう。

    { // 約分処理
      Fraction fraction1 = new Fraction(72, 256);
      System.out.println(fraction1 + " --> " + fraction1.reduce());
    }

Fraction のインスタンスを作り、それのreduce() 関数を呼ぶと約分結果が返ってきます。
実行すると以下のようになりました。

72/256 --> 9/32

なかなか便利です。


次は通分処理です。
ええと、ここで告白するなら、実は私は通分もFraction クラスのインスタンスメソッドとして実装するつもりだったのですが、よく考えると通分は2つ以上の分数に対してそれぞれの分母を揃えるというものなので、インスタンスメソッドには出来ないですね。
ということで、今はその処理を丁寧に記述するに留めます。
具体的には以下のようになります。
ソースコード

    { //通分処理
      Fraction fraction1 = new Fraction(11, 24);
      Fraction fraction2 = new Fraction(7, 15);
      long lcm = MathUtil.lcm(
        fraction1.getDenominator(), fraction2.getDenominator()
      );
      Fraction fraction1a = new Fraction(
        fraction1.getNumerator() * lcm / fraction1.getDenominator(),
        lcm
      );
      Fraction fraction2a = new Fraction(
        fraction2.getNumerator() * lcm / fraction2.getDenominator(),
        lcm
      );
      System.out.println("fraction1: " + fraction1 + " --> " + fraction1a);
      System.out.println("fraction2: " + fraction2 + " --> " + fraction2a);
    }

fraction1(11/24)とfraction2(7/15)という分数を用意してそれぞれの分母の最小公倍数(lcm)を求めます。
次にlcm の値から、それぞれの分子に通分処理を施します。分子にlcm の値を掛け、次に分母で割ります。計算結果を分子、lcm を分母にした新しいFraction インスタンスが、通分の結果となります。
上記の処理を実際に実行してみると、以下のような結果になります。

fraction1: 11/24 --> 55/120
fraction2: 7/15 --> 56/120

これで、足し算のための前処理は終了ですね。