I haven’t seen any other techniques for converting real number’s into fractions on this forum, so I just thought I’d share this version.
Along with ‘fractionising’ normal rational numbers, I have added a small example to illustrated how multiples of pi and any other known irrational numbers can also be found.
This has not been properly tested, so some bugs might be present.
I look forward to other versions that people have or any improvements on mine.
property tolerance : 10 -- Number of repeats
property minimumRemainder : 1.0E-7
property piSymbol : «data utxt03C0» as Unicode text
property squareRootSymbol : «data utxt221A» as Unicode text
-- Set up list of units
set unitList to {{unit:1, symbol:null}, {unit:pi, symbol:piSymbol}, {unit:(2 ^ 0.5), symbol:(squareRootSymbol & 2)}}
fractionise(2 ^ 0.5 * 0.45, unitList, tolerance, minimumRemainder)
--> "9√2/20"
fractionise(3 * pi / 4, unitList, tolerance, minimumRemainder)
--> "3Ï€/4"
fractionise(12347 / 14512, unitList, 15, 1.0E-5) -- Custom tolerance levels
--> "12347/14512"
on fractionise(theNumber, unitList, tolerance, minimumRemainder)
repeat with thisUnit in unitList
tell fractionParts(theNumber / (thisUnit's unit), tolerance, minimumRemainder) to if it is not false then ¬
return my formatFraction(it, thisUnit's symbol)
end repeat
return false
end fractionise
on fractionParts(n, tolerance, minimumRemainder)
if n mod 1 is 0 then return {numerator:n div 1, denominator:1}
set i to n
set b to 1
repeat tolerance times
if i < 1 then
set remainder to i
else
set remainder to i - i div 1 -- Does the same as 'i mod 1', but more accurate
end if
if remainder < minimumRemainder then return {numerator:(n * b div 1), denominator:b div 1}
set i to 1 / remainder
set b to b * i
end repeat
return false
end fractionParts
on formatFraction(fraction, unitSymbol)
tell fraction
if unitSymbol is null then
set fracString to its numerator as Unicode text
else if its numerator is 1 then
set fracString to unitSymbol
else
set fracString to (its numerator as Unicode text) & unitSymbol
end if
if its denominator is not 1 then set fracString to fracString & "/" & its denominator
end tell
return fracString
end formatFraction