January 17, 2021
Hot Topics:

Implementing a Decimal-to-Fraction Class with Operator Overloading

  • By Paul Kimmel
  • Send Email »
  • More Articles »

Finding the Denominator

The denominator is also pretty straightforward. The denominator is always 10nth where n is the length of the numerator. For example, a numerator of 234 has a denominator of 1,000 or 103. You can use Math.Exp and the length of the numerator to calculate the denominator (as shown next).

Private Sub SetDenominator(ByVal fraction As String)
   Denominator = Math.Pow(10, fraction.Length)
End Sub

The field fraction is set in an overloaded SetFractionalPart method that truncates the length of the decimal number to eight characters to ensure that it fits in an integer. (If you need a longer fraction, use a long data type.) Here is the overloaded SetFractionalPart method.

Private Sub SetFractionalPart(ByRef fraction As String)
   If (fraction.Length > 8) Then
      fraction = fraction.Substring(0, 8)
   End If

   _fractionalNumber = _
      Math.Round(Convert.ToDouble("." + fraction), 8)
End Sub

Factoring and Reducing with the Euclidean Algorithm

The final step is to find the greatest common divisor and reduce the numerator and denominator by this divisor. You can use the Euclidean algorithm—discovered by Euclid around 300 BC—that uses division, modular arithmetic, and remainders to quickly resolve the greatest common divisor. Here is a non-recursive Euclidean Gcd algorithm and a helper function that reduces the fraction.

Private Function Gcd(ByVal num As Integer, _
                     ByVal den As Integer) As Integer

   If (den Mod num = 1) Then Return 1
   While (den Mod num <> 0)
      Dim temp As Integer = num
      num = den Mod num
      den = temp
   End While

   Return num

End Function

Private Sub ReduceWithGcd()

   Dim divisor As Integer = Gcd(_numerator, _denominator)
   _numerator   = _numerator / divisor
   _denominator = _denominator / divisor

End Sub

That's it. You are finished. I will wrap up the discussion with some examples of overloaded operators that will permit arithmetic operations on Fraction objects.

Implementing Custom Operators

Overloaded operators are shared methods that accept the number and type of arguments based on the operator count. For example, - (subtraction) is a binary operator, so to support Fraction subtraction you need a shared method that takes two Fraction arguments. Operators also use the operator keyword. Here is an implementation of the subtraction operator for your Fraction class.

Public Shared Operator -(ByVal lhs As Fraction, _
                         ByVal rhs As Fraction) _
   As Fraction
   Return New Fraction(rhs.Number - lhs.Number)
End Operator

Operators are often perceived to be hard, but they are pretty intuitive. For the most part, the rule is that you need to implement symmetric operations. For example, if you implement subtraction, you should then implement addition. The other rule is don't add side effects or change the understood behavior of an operator. For example, the addition operator should perform some kind of arithmetic operation.

Listing 1 contains the complete implementation of the Fraction class, including several examples of overloaded operators for you to experiment with.

Page 2 of 4

This article was originally published on August 15, 2007

Enterprise Development Update

Don't miss an article. Subscribe to our newsletter below.

Thanks for your registration, follow us on our social networks to keep up-to-date