Function dec2frac(ByVal dblDecimal As Double) As String
'
' Excel function to convert decimal values to integer fractions.
'
' Original Written by: Erik Oosterwal
' Converted to .NET by: Chris Anderson
' Started on: November 16, 2006
' Completed on: November 16, 2006
' Converted on: February 25, 2007
'
Dim intNumerator, intDenominator, intNegative As Integer
' Declare integer variables
Dim dblFraction, dblAccuracy As Double
' Declare floating point variables as double precision.
Dim txtDecimal As String
' need a string representation of the input value
' in order to determine the required accuracy.
' Find the accuracy needed for the output by checking the number of digits behind the decimal point
' of the input value.
'
' dblAccuracy = 1 / 10 ^ (Len(CStr(dblDecimal - Fix(dblDecimal))) - 2)
'
' While the formula above should work, there is a serious error in the way Excel handles
' decimal numbers and there's a huge rounding error issue. Subtracting the int() of
' 12.1 from 12.1 produces 0.0999999999 or something similar. Obviously that won't
' work for our desired accuracy of the magnitude of the fractional part of the number
' so a slower more cumbersome method has to be used...
dblAccuracy = 0.1 ' Set the initial Accuracy level.
txtDecimal = dblDecimal.ToString ' Get a string representation of the input number.
For i As Integer = 0 To (txtDecimal.Length - 1) ' Check each character to see if it's a decimal point...
If txtDecimal.Substring(i, 1) = "." Then ' if it is then we get the number of digits behind the decimal
dblAccuracy = 1 / 10 ^ (txtDecimal.Length - i) ' assign the new accuracy level, and
Exit For ' exit the for loop.
End If
Next
intNumerator = 0 ' Set the initial numerator value to 0.
intDenominator = 1 ' Set the initial denominator value to 1.
intNegative = 1 ' Set the negative value flag to positive.
If dblDecimal < 0 Then
intNegative = -1 ' If the desired decimal value is negative,
' then set the negative value flag to
' negative.
End If
dblFraction = 0 ' Set the fraction value to be 0/1.
Do While Math.Abs(dblFraction - dblDecimal) > dblAccuracy ' As long as we're still outside the
' desired accuracy, then...
If Math.Abs(dblFraction) > Math.Abs(dblDecimal) Then ' If our fraction is too big,
intDenominator += 1 ' increase the denominator
Else ' Otherwise
intNumerator += intNegative ' increase the numerator.
End If
dblFraction = intNumerator / intDenominator ' Set the new value of the fraction.
Loop
Return intNumerator.ToString & "/" & intDenominator.ToString ' Display the numerator and denominator
End Function