[VBA] 分数同士の加算(減算)・乗算・除算を分数で返します

 数値計算では「割り算(除算)によって精度が落ちる」という問題が常につきまといます。たとえば VBA で 1/3 のような計算をさせると

 0.333333333333333

という 15 桁の数値を返します。本来であれば 1/3 の小数点以下は無限に続くわけですから、これだけでも僅かに精度を落としてしまっているのです。つまり数値計算では 1/2 + 1/3 というような簡単な計算さえも正しい答えを返さないことになってしまいます。そこで、こうした事態を防ぐために 分数同士の計算は分数で返す ような関数をつくることを考えてみます。

分数型変数を定義します

 そのためにはユーザー定義変数(構造体)によって分数型変数を定義する必要があります。宣言セクションに以下のステートメントを書き込んでください。

 '分数型変数の定義
 Type Fraction
  num As Long
  den As Long
 End Type

 Fraction型変数は分子 (numerator) に相当する num と、分母 (denominator) に相当する den という2つの変数を同時に格納することになります。
 

2つの引数を与えて分数を定義します

 分子 a と分母 b を指定して分数を定義する FRAC関数です。

 '分数の定義
 '(C)BlogCat https://excelmath.atelierkobato.com/vba-fraction/

 Function FRAC(a As Long, b As Long) As Fraction

  Dim fgcd As Long

  'aとbの最大公約数を計算
  fgcd = WorksheetFunction.Gcd(a, b)

  '約分します
  FRAC.num = a / fgcd
  FRAC.den = b / fgcd

 End Function

 この関数を呼びだすときは

FRAC(分子,分母)

のように記述します。答えは約分された形で返されます。たとえば

 Sub FRACtest()

  Dim x As Fraction

  x = FRAC(3, 6)

  Debug.Print x.num & "/" & x.den

 End Sub

というマクロを実行すると 3/6 を約分して 1/2 という値が表示されます。
 

分数の加算(減算)

 2つの分数を与えて和を返す SUMFRAC関数です。

 '分数の加算
 '(C)BlogCat https://excelmath.atelierkobato.com/vba-fraction/

 Function SUMFRAC(f1 As Fraction, f2 As Fraction) As Fraction

  Dim f3num As Long
  Dim f3den As Long
  Dim f3gcd As Long

  f3num = f1.num * f2.den + f1.den * f2.num
  f3den = f1.den * f2.den

  f3gcd = WorksheetFunction.Gcd(f3num, f3den)

  SUMFRAC.num = f3num / f3gcd
  SUMFRAC.den = f3den / f3gcd

 End Function

 SUMFRAC関数は

SUMFRAC(分数1,分数2)

という形で呼びだします。たとえば 1/2 + 1/3 を計算させる場合は次のようなコードを書きます。

 Sub SUMFRACtest()

  Dim f1 As Fraction
  Dim f2 As Fraction
  Dim f3 As Fraction

  f1 = FRAC(1, 2)
  f2 = FRAC(1, 3)
  f3 = SUMFRAC(f1, f2)

  Debug.Print f3.num & "/" & f3.den

 End Sub

 実行すると 5/6 という値が返ります。引き算をさせたいときは引くほうの分数を

FRAC(-1,3)

のように書きます。
 

分数の乗算

 分数同士の掛け算をする PDTFRAC関数です。

 '分数の乗算
 '(C)BlogCat https://excelmath.atelierkobato.com/vba-fraction/

 Function PDCFRAC(f1 As Fraction, f2 As Fraction) As Fraction

  Dim f3num As Long
  Dim f3den As Long
  Dim f3gcd As Long

  f3num = f1.num * f2.num
  f3den = f1.den * f2.den
  f3gcd = WorksheetFunction.Gcd(f3num, f3den)

  PDCFRAC.num = f3num / f3gcd
  PDCFRAC.den = f3den / f3gcd

 End Function

 PDCFRAC関数は

PDCFRAC(分数1,分数2)

という形で呼びだします。たとえば 2/7 × 3/5 を計算させる場合は次のようなコードを書きます。

 Sub PDCFRACtest()

  Dim f1 As Fraction
  Dim f2 As Fraction
  Dim f3 As Fraction

  f1 = FRAC(2, 7)
  f2 = FRAC(3, 5)
  f3 = PDCFRAC(f1, f2)

  Debug.Print f3.num & "/" & f3.den

 End Sub

 このマクロを実行すると 6/35 という値が返ります。
 

分数の除算

 分数同士の割り算をする DIVFRAC関数です。

 '分数の除算
 '(C)BlogCat https://excelmath.atelierkobato.com/vba-fraction/

 Function DIVFRAC(f1 As Fraction, f2 As Fraction) As Fraction

  Dim f3num As Long
  Dim f3den As Long
  Dim f3gcd As Long

  f3num = f1.num * f2.den
  f3den = f1.den * f2.num
  f3gcd = WorksheetFunction.Gcd(f3num, f3den)

  DIVFRAC.num = f3num / f3gcd
  DIVFRAC.den = f3den / f3gcd

 End Function

 DIVFRAC関数は

DIVFRAC(分数1,分数2)

という形で呼びだします。たとえば 3/2 ÷ 4/3 を計算させるときには次のようなマクロを実行します。

 Sub DIVFRACtest()

  Dim f1 As Fraction
  Dim f2 As Fraction
  Dim f3 As Fraction

  f1 = FRAC(2, 3)
  f2 = FRAC(3, 4)
  f3 = DIVFRAC(f1, f2)

  Debug.Print f3.num & "/" & f3.den

 End Sub

 分数型変数を使うと、有限項の数列の和などを分数の形で得るなど色々なところで応用できます。 ≫ VBA 数値計算

スポンサーリンク
スポンサーリンク
末尾広告
末尾広告

コメントをどうぞ

メールアドレスが公開されることはありません。

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください