floatToFraction UDF

Someone on CF-Talk just asked about converting floating point numbers back to decimals.  Always one to enjoy a little abstract thought on a random topic during my lunch, I threw together a solution:

function floatToFraction(num, maxDenom) {
var denom = "";
var numer = "";
var intPart = fix(num);
var sigFigs = "";
if (num EQ intPart) {
return num;
}
num = num – intPart;
sigFigs = len(num) – 2;
for (denom = 2; denom LTE maxDenom; denom = denom + 1) {
for (numer = 1; numer LT denom; numer = numer + 1) {
if (round(numer / denom * (10 ^ sigFigs)) / (10 ^ sigFigs) EQ num) {
if (intPart NEQ 0) {
return intPart & " " & numer & "/" & denom;
} else {
return numer & "/" & denom;
}
}
}
}
return intPart + num;
}

It's not perfect (feed it 0.7, for example), but it's a good start.  The tricky case is catching the irrational fractions (which is the source of the above mentioned imperfection), but a little clever rounding and it's easily solved for the majority of cases.  The maxDenom argument is for controlling the granularity of the fractions returned.  If, for example, you don't want to get any finder than eighths, you can pass 8 in as the maxDenom value and anything that would require a denominator of larger than eight will simply be returned as the floating point number passed in (e.g. floatToFraction(0.9, 8) will return 0.9, while floatToFraction(0.9, 10) will return 9/10).

Comments are closed.