[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関数です。

'VBA 分数の定義

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を呼びだすときは

FRAC(分子,分母)

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

'VBA 分数関数のテスト

Sub FRAC_test()

  Dim x As Fraction

  x = FRAC(3, 6)

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

 End Sub

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

分数の加算(減算)

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

'VBA 分数の加算関数の定義

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 を計算させる場合は次のようなコードを書きます。

'VBA 分数の加算関数の定義

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関数です。

'VBA 分数の乗算関数の定義

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 を計算させる場合は次のようなコードを書きます。

'VBA 分数の乗算関数のテスト

Sub PDCFRAC_test()

  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関数です。

'VBA 分数の除算関数の定義

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 を計算させるときには次のようなマクロを実行します。

'VBA 分数の除算関数のテスト

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

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


 

コメントをどうぞ

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