-3

I am trying to write a program in Python which approximates a real number by a fraction up to precision 10^-3. Here is what I did, I don't know what's wrong. Can someone help me ? I use the "clockwork addition". Can someone tell me what's wrong with it ? thanks in advance.

from math import *

def restriction(x,a,b,c,d):

    if x<(a+b)/(c+d):
        return [x,a,b,a+c,b+d]
    if x>(a+b)/(c+d):
        return [x,a+c,b+d,c,d]

def cancres(x,a,b,c,d,prec):

    if x==a/b or x==c/d:
        return x
    elif x<a/b or x>c/d:
        return False
    else:
        w=restriction(x,a,b,c,d)
        i=0
        if (w[3]/w[4]-w[2]/w[1])>prec:
            w=restriction(x,w[1],w[2],w[3],w[4])
            print w
            i+=1
    return w

print cancres(sqrt(3),3,2,2,1,10^(-3))
William Denman
  • 3,046
  • 32
  • 34
Asinus
  • 125
  • 4
  • Well, what **is** wrong? – Oliver Charlesworth Dec 15 '13 at 16:24
  • ^ doesn't do exponentiation. Try replacing 10^(-3) with 10**(-3) . – casevh Dec 15 '13 at 16:26
  • It just won't find a fraction. I think it might be because of a type error in the calculations. – Asinus Dec 15 '13 at 16:26
  • It's not a duplicate, I don't just want to use the python command for approximation, I want to test my algorithm. Thanks for your time. – Asinus Dec 15 '13 at 16:29
  • 1
    This is a really strange function. It can return either a `float` (`return x`), a `bool` (`return False`), or a list of four `float`s (`return w`). None of which seems to be a ratio of two integers. There's not really a way to tell why it doesn't work when it isn't even clear what it's supposed to return. – interjay Dec 15 '13 at 16:53

1 Answers1

0

There are several errors in your program. First, the expression 10^(-3) doesn't evaluate to 0.001. ^ is used for the exclusive-or bit-by-bit operation between two integers. Python uses ** for exponentiation.

Second, it looks like you are using Python 2.x. Python 2.x uses integer division by default. So 3/2 returns 1 and not 1.5. Python 3.x changes the behavior to return a float. With Python 2.x, you either need to convert one operand of each division to a float or use from __future__ import division to use Python 3.x style division with Python 2.x.

The line if (w[3]/w[4]-w[2]/w[1])>prec: has three errors. It should be w[4]/w[3] instead of w[3]/w[4]. You need to take the absolute value before comparing with prec. And you are trying to perform a repeated loop so you should use while instead of if.

There are some other design and stylistic issues that I didn't address but the code appears to work.

from __future__ import division
from math import *

def restriction(x,a,b,c,d):

    if x<(a+b)/(c+d):
        return [x,a,b,a+c,b+d]
    if x>(a+b)/(c+d):
        return [x,a+c,b+d,c,d]

def cancres(x,a,b,c,d,prec):

    if x==a/b or x==c/d:
        return x
    elif x<a/b or x>c/d:
        return False
    else:
        w=restriction(x,a,b,c,d)
        i=0
        while (abs(w[4]/w[3]-w[2]/w[1]))>prec:
            w=restriction(x,w[1],w[2],w[3],w[4])
            print w
            i+=1
    return w

print cancres(sqrt(3),3,2,2,1,10**(-3))
casevh
  • 11,093
  • 1
  • 24
  • 35