Finding out the closest approximation of a decimal number by a ratio of two integers

Given a decimal number, which is positive but can be less than or greater than one, how to find out its best approximation by a ratio of two integers in a given range? For example, given a number a = 0.647437, I would like to find the ratio b/c that is closest to a, where b and c are integers in the common range 1 ~ 20. What can be one of the most concise ways to do this?

• Look up Rationalize[]. Dec 9 '16 at 22:30
• In:= Select[Convergents[ContinuedFraction[0.647437]], Numerator[#] <= 20 && Denominator[#] <= 20 &][[-1]] Out= 11/17 Dec 9 '16 at 22:40
• @J. M.♦ I think it is not what I am looking for. I do not care much about the absolute precision of the result, but the best approximation out of the range I designate. For the 0.647437 number, I do not need 90/139, but 11/17 if the range is 1~20 or 2/3 if the range is 1~5. Dec 9 '16 at 22:40
• perhaps f[r_, n_] := Divide@@Sort[Map[{Abs[Divide@@ #-r],#}&, Union[Flatten[Outer[List, Range[n], Range[n]],1]]]][[1,2]] where f[0.647437, 20] gives 11/7 and f[0.647437, 5] gives 2/3. Perhaps there is some way to search over all possible mathematica functions less than or equal to that length and which produce the same result to find the "most concise way" to do this. That would be an interesting tool to have.
– Bill
Dec 9 '16 at 23:09
• have you tried working with the second argument to Rationalize? Dec 10 '16 at 0:18

Here is a brute-force version of bobby's answer:

Table[First[MinimalBy[FareySequence[k], Abs[0.647437 - #] &]], {k, {5, 20, 1000}}]
{2/3, 11/17, 101/156}
• Yours at least reduces the fraction and interestingly uses the Farey sequence. +1 Dec 9 '16 at 23:34
• It helps that all the fractions in the Farey sequence are already in lowest terms... Dec 9 '16 at 23:40
• Damn you no!!! No brute force!!! Use ContinuedFraction, select an appropriate number of terms, then apply FromContinuedFraction Dec 10 '16 at 6:52

Try this

Minimize[{Abs[.647437 - a/b], 6 > a > 0, 6 > b > 0}, {a, b}, Integers]

({0.0192297, {a -> 2, b -> 3}})

Minimize[{Abs[.647437 - a/b], 21 > a > 0, 21 > b > 0}, {a, b}, Integers]

({0.000378176, {a -> 11, b -> 17}})

Minimize[{Abs[.647437 - a/b], 1001 > a > 0, 1001 > b > 0}, {a, b}, Integers]

(*{1.10256*10^-6, {a -> 404, b -> 624}}*)

• Of course, you can do Divide @@ NArgMin[{Abs[.647437 b - a], 1001 > a > 0, 1001 > b > 0}, {a, b}, Integers] if all you want is the fraction itself. (Note the reformulation such that division is avoided in the objective function.) Dec 9 '16 at 23:38
• @J. M. Very cunning +1, thanks. Dec 9 '16 at 23:55