Hello all, it's your friendly neighborhood post-n-runner!
Anyway, today's post is a pair of Functions that can be used to convert a Decimal ("computer readable") number into a Fractional ("human readable") number!
First off, I'll point out that yes, decimal numbers are human readable too. However, fractional numbers are most definitely NOT computer readable. And, since there are several industries (and numerous personal projects) that like to see fractional numbers, here's an easy way of providing that.
The code (supplied below) will allow you to specify a "maximum" denominator, essentially telling the computer your smallest value. If the decimal value doesn't fit exactly, then it will be rounded to the closest decimal number that does:
For example, if you try to convert 6.4 into a fractional representation, but specify a maximum denominator of "2", you'll get "6-1/2" since 0.5 is the closest decimal value that can be divided into halves.
A handful of quick examples, and then onto the code!
GetFraction(0.5, 2, " ") = "1/2"
GetFraction(1.5, 2, " ") = "1 1/2"
GetFraction(1.5, 2) = "1-1/2"
GetFraction(1.5, 4) = "1-1/2"
GetFraction(19.375, 16) = "19-3/8"
GetFraction(19.38, 16) = "19-3/8"
Code:
Public Function GetFraction(Number As Double, Optional Denominator As Long = 32, Optional Spacer As String = "-") As Variant
' This function returns a fractional representation of a decimal number.
' Number = The decimal representation of the number you want to convert.
' Required.
' Denominator = The max value of the denominator that will be accepted after
' conversion. Will round the number as necessary to find the nearest
' acceptable value. It ignored, will default to 64ths.
' Spacer = The spacing character to be used between the integral and
' fractional values of the converted number. Typically a space " " or dash
' "-". If ignored, will default to a dash.
Dim nbrGCD As Long
Dim nbrNumerator As Long
GetFraction = -1 ' Initial value!
If Int(Number) = Number Then
GetFraction = CStr(Number)
Else
' Round the number to the closest possible value (within the limitations of
' our specified Denominator)
nbrNumerator = CLng((Number - Int(Number)) * Denominator)
' Find the GCD of our (rounded) Numerator and Denominator numbers
nbrGCD = GetGCD(nbrNumerator, Denominator)
' Just in case, specify 1 as the lowest possible GCD
If nbrGCD <= 0 Then
nbrGCD = 1
End If
' Use the GCD to reduce our fraction to the "lowest" possible value
nbrNumerator = nbrNumerator / nbrGCD
Denominator = Denominator / nbrGCD
' Return the resulting fractional number (as a String)
If Int(Number) = 0 Then
GetFraction = CStr(CLng(nbrNumerator)) & "/" & Denominator
Else
GetFraction = CStr(Int(Number)) & Spacer & CStr(CLng(nbrNumerator)) & "/" & Denominator
End If
End If
End Function
Public Function GetGCD(Number1 As Long, Number2 As Long) As Long
Dim nbrN1 As Long
Dim nbrN2 As Long
Dim nbrTmp As Long
nbrN1 = Number1
nbrN2 = Number2
Do While nbrN1
If nbrN1 < nbrN2 Then
nbrTmp = nbrN1
nbrN1 = nbrN2
nbrN2 = nbrTmp
End If
nbrN1 = nbrN1 Mod nbrN2
Loop
GetGCD = nbrN2
End Function