雨谷の日和

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

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

ではいよいよ、分数同士の掛け算・割り算を実装してみます。
まずは掛け算から。

  public Fraction multiply(Fraction dst){
    if(this.isZero() || this.isInfinity())return this;
    if(dst.isZero() || dst.isInfinity())return dst;
    return this.multiply(dst.numerator).divide(dst.denominator);
  }

自分自身が0か無限大、もしくは相手が0か無限大の場合には、それをそのまま返します。0に何を掛けても0ですし、無限大に何を掛けても無限大ですから。
じゃあ、0と無限大を掛けたらどうなるんだ?という疑問もあるかと思いますが、とりあえずそれは無視の方向で。そこまで厳密に考える必要は、実用上あまり無いので。
いずれの分数も0、無限大でない場合には、実際の計算をします。
互いの分子と分子、分母と分母を掛け合わせて……とやりたいところですが、そこは以前に書いたmultiply とdivide を再利用しましょう。
自分自身に相手の分子をmultiply し、その結果を今度は相手の分母でdivide すれば、同じ事ですね。


さて、今度は割り算ですが、分数の割り算は相手の分子分母をひっくりかして掛ければ良いわけです。
ということで、分子分母をひっくり返す関数も用意します。

  public Fraction invert(){
    return new Fraction(denominator, numerator);
  }

invert 関数と先のmultiply 関数を使うと、割り算は以下のようになりますね。
ソースコード

  public Fraction divide(Fraction dst){
    return this.multiply(dst.invert());
  }

では実際に使ってみましょう。
1/3 を掛けたり、1/3 で割ったりするサンプルコードは以下のようになります。
ソースコード

    { // 1/3 を掛けてみる
      Fraction result = fraction.multiply(new Fraction(1, 3));
      print(result);
    }
    { // 1/3 で割ってみる
      Fraction result = fraction.divide(new Fraction(1, 3));
      print(result);
    }

実行結果は以下のような感じに。

result: 1/6 [false, false]
result: 3/2 [false, false]

問題無さそうですね。