August 22, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

Implementing a Decimal-to-Fraction Class with Operator Overloading

  • August 15, 2007
  • By Paul Kimmel
  • Send Email »
  • More Articles »

Listing 1: The complete listing of the Fraction class.

Public Class  Fraction

   Public Sub New(ByVal number As Double)
      _number = Math.Round(number, 8)
      Dim value As String = _number.ToString()

      SetSign(value)
      Dim index As Integer = CheckNoDecimalPoint(number)
      If (index = -1) Then Return

      SetWholePart(value, index)
      SetFractionalPart(value, index)

   End Sub

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

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

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

   Public Shared Operator <>(ByVal lhs As Fraction, _
                             ByVal rhs As Fraction) _
      As Boolean
      Return rhs.Number <> lhs.Number
   End Operator

   Public Shared Widening Operator CType(ByVal rhs As Fraction) _
      As Double
      Return rhs.Number
   End Operator

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

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

   Public Shared Narrowing Operator CType(ByVal number As Double) _
      As Fraction
      Return New Fraction(number)
   End Operator

   Public Sub New(ByVal number As String)
      Me.New(Convert.ToDouble(number))
   End Sub

   Private _number As Double
   Public Property Number() As Double
      Get
         Return _number
      End Get
      Set(ByVal Value As Double)
         _number = Value
      End Set
   End Property

   Private _sign As Integer = 1
   Public Property Sign() As Integer
      Get
         Return _sign
      End Get
      Set(ByVal Value As Integer)
         _sign = Value
      End Set
   End Property

   Private _numerator As Integer = 0
   Public Property Numerator() As Integer
      Get
         Return _numerator
      End Get
      Set(ByVal Value As Integer)
         _numerator = Value
      End Set
   End Property

   Private _denominator As Integer = 1
   Public Property Denominator() As Integer
      Get
         Return _denominator
      End Get
      Set(ByVal Value As Integer)
         _denominator = Value
      End Set
   End Property

   Private _fractionalNumber As Double
   Public Property FractionalNumber() As Double
      Get
         Return _fractionalNumber
      End Get
      Set(ByVal Value As Double)
         _fractionalNumber = Value
      End Set
   End Property

   Private _wholeNumber As Integer
   Public Property WholeNumber() As Integer
      Get
         Return _wholeNumber
      End Get
      Set(ByVal Value As Integer)
         _wholeNumber = Value
      End Set
   End Property

   Private Sub SetSign(ByVal value As String)

      If (Regex.IsMatch(value, "^-")) Then
         Sign = -1
      End If

   End Sub


   Private Function CheckNoDecimalPoint(ByVa number As Double) _
      As Integer

      Dim index As Integer = number.ToString().LastIndexOf(".")

      If (index = -1) Then
         WholeNumber = Convert.ToInt32(number)
      End If

      Return index

   End Function

   Private Sub SetWholePart(ByVal value As String, _
                            ByVal index As Integer)

      Dim whole As String = value.Substring(0, index)
      If (whole.Length > 0) Then
         WholeNumber = Convert.ToInt32(whole)
      End If

   End Sub

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

   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

   Private Sub SetFractionalPart(ByVal value As String, _
                                 ByVal index As Integer)

      Dim fraction As String = value.Remove(0, index + 1)

      If (fraction.Length > 0) Then
         SetFractionalPart(fraction)
         _numerator = Convert.ToInt32(fraction)
         SetDenominator(fraction)
         ReduceWithGcd()
      End If
   End Sub

   Private Sub ReduceWithGcd()

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

   End Sub

   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

   Public Overrides Function ToString() As String

      If (FractionalNumber = 0 And WholeNumber = 0) Then
         Return ""
      End If

      Dim builder As StringBuilder = New StringBuilder()
      If (Sign = -1) Then builder.Append("-")

      If (Math.Abs(WholeNumber) <> 0) Then

         If (FractionalNumber = 1) Then
            builder.Append(Math.Abs(WholeNumber) + 1)
            Return builder.ToString()
         Else
            builder.Append(Math.Abs(WholeNumber))
            builder.Append(" ")
         End If
      End If

      If (FractionalNumber <> 0) Then
         builder.Append(Numerator.ToString())
         builder.Append("/")
         builder.Append(Denominator.ToString())
      End If

      Return builder.ToString()
   End Function

End Class




Page 3 of 4



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel