I recently needed a way to convert decimal values into their fraction counterparts. A search on Google turned up this little gem: http://www.geocities.com/oosterwal/c...onversion.html originally written for VBA/VB6. Naturally I'm working in .NET, so I converted the code to VB.NET.

VB Code:
  1. Function dec2frac(ByVal dblDecimal As Double) As String
  2.         '
  3.         '   Excel function to convert decimal values to integer fractions.
  4.         '
  5.         '   Original Written by:     Erik Oosterwal
  6.         '   Converted to .NET by:     Chris Anderson
  7.         '   Started on:     November 16, 2006
  8.         '   Completed on:   November 16, 2006
  9.         '   Converted on:   February 25, 2007
  10.         '
  11.  
  12.         Dim intNumerator, intDenominator, intNegative As Integer
  13.         ' Declare integer variables
  14.         Dim dblFraction, dblAccuracy As Double
  15.         ' Declare floating point variables as double precision.
  16.         Dim txtDecimal As String
  17.         ' need a string representation of the input value
  18.         ' in order to determine the required accuracy.
  19.  
  20.         ' Find the accuracy needed for the output by checking the number of digits behind the decimal point
  21.         '   of the input value.
  22.         '
  23.         '    dblAccuracy = 1 / 10 ^ (Len(CStr(dblDecimal - Fix(dblDecimal))) - 2)
  24.         '
  25.         '   While the formula above should work, there is a serious error in the way Excel handles
  26.         '   decimal numbers and there's a huge rounding error issue.  Subtracting the int() of
  27.         '   12.1 from 12.1 produces 0.0999999999 or something similar.  Obviously that won't
  28.         '   work for our desired accuracy of the magnitude of the fractional part of the number
  29.         '   so a slower more cumbersome method has to be used...
  30.  
  31.         dblAccuracy = 0.1                                       ' Set the initial Accuracy level.
  32.         txtDecimal = dblDecimal.ToString                        ' Get a  string representation of the input number.
  33.  
  34.         For i As Integer = 0 To (txtDecimal.Length - 1)                                 ' Check each character to see if it's a decimal point...
  35.             If txtDecimal.Substring(i, 1) = "." Then                    ' if it is then we get the number of digits behind the decimal
  36.                 dblAccuracy = 1 / 10 ^ (txtDecimal.Length - i)    '   assign the new accuracy level, and
  37.                 Exit For                                            '   exit the for loop.
  38.             End If
  39.         Next
  40.  
  41.         intNumerator = 0                                ' Set the initial numerator value to 0.
  42.         intDenominator = 1                              ' Set the initial denominator value to 1.
  43.         intNegative = 1                                 ' Set the negative value flag to positive.
  44.  
  45.         If dblDecimal < 0 Then
  46.             intNegative = -1 ' If the desired decimal value is negative,
  47.             '   then set the negative value flag to
  48.             '   negative.
  49.         End If
  50.  
  51.         dblFraction = 0                                 ' Set the fraction value to be 0/1.
  52.  
  53.         Do While Math.Abs(dblFraction - dblDecimal) > dblAccuracy   ' As long as we're still outside the
  54.             '   desired accuracy, then...
  55.             If Math.Abs(dblFraction) > Math.Abs(dblDecimal) Then      ' If our fraction is too big,
  56.                 intDenominator += 1         '   increase the denominator
  57.             Else                                            ' Otherwise
  58.                 intNumerator += intNegative   '   increase the numerator.
  59.             End If
  60.  
  61.             dblFraction = intNumerator / intDenominator     ' Set the new value of the fraction.
  62.  
  63.         Loop
  64.  
  65.         Return intNumerator.ToString & "/" & intDenominator.ToString ' Display the numerator and denominator
  66.     End Function

It's not the prettiest, and it could probably be written a little more streamlined, but it does work. If anyone has any suggestions for improvement, please do.

-tg