Implementing a Decimal-to-Fraction Class with Operator Overloading, Page 3
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
0 Comments (click to add your comment)
Networking Solutions
