1

So, How to write a python code which finds a rational number, which is closed to a fraction say f, without the use of standard function modules?

E.g., 3.14=22/7

Also the numerator and denominators have limits, like:

  • numerator can't be greater than p
  • denominator can't be greater than q.

My work:

# calculates i/j upto a precision of 0.001 closer to f.
while( abs((i/j)-f)> 0.001 and i<p, j<q):
    j=j-1
    i =?, 

Now here I'm confused, How should I modify my i and j to make it work? Can I use Newton Raphson algorithm in any way??

atline
  • 28,355
  • 16
  • 77
  • 113
Paranoid
  • 111
  • 2

2 Answers2

0

Pythons standard library has a module for this:

print(fractions.Fraction.from_float(math.pi).limit_denominator(30))

outputs

22/7

A brute force approach:

import math

def approx(number, p):
    best = None
    best_dist = number
    for d in range(1, p + 1):
        n0 = int(d / number)
        for n in (n0 -1, n0, n0 + 1):
            if n <= 0:
                continue
            dist = abs(number - d / n)
            if dist < best_dist:
                best_dist = dist
                best = (d, n)
    return best


print(approx(math.pi, 30))

outputs

(22, 7)

And then there is a third option: https://www.johndcook.com/blog/2010/10/20/best-rational-approximation/

rocksportrocker
  • 7,251
  • 2
  • 31
  • 48
0

Consider that array [1,..q]

Then multiply each element by the given fraction f then check the nearest element to p .I think this algorithm would execute in O(q) . well , you can improve upon the algorithm to check it p or q is smaller and then do likewise

import math
def foo(f,p,q):
    m=9999

    for i in range(1,q+1):
        reqp=round(f*i)

        if(  abs((float(reqp)/i) -f ) <m and reqp>0 and reqp <=p ):
            m=abs(float(reqp)/i-f)
            values = [reqp,i]
    return values

print(foo(3.14,30,30))            

OUTPUT

[22.0, 7]
Albin Paul
  • 3,330
  • 2
  • 14
  • 30