1

I want to make a program that gives a list of all the integers resulting from the expression y = sqrt(16 + x**2) for x in [-100,100] I have tried this

def num():
    x= []
    for y in range (-100,100):
        z = (16+y**2)**0.5 
        if isinstance(z,int):
            x.append(z)
    return(x) 

but I had the problem that the function sqrt() always gives a float e.g.

sqrt(16+3**2)

Out[20]: 5.0

Stuart Buckingham
  • 1,574
  • 16
  • 25
user382662
  • 11
  • 2
  • 1
    Hint: [`float.is_integer`](https://docs.python.org/3/library/stdtypes.html#float.is_integer) – Mark Dickinson Oct 12 '17 at 19:06
  • Possible duplicate of [How Can I Put type() with if statement in python?](https://stackoverflow.com/questions/29567768/how-can-i-put-type-with-if-statement-in-python) – Mark Dickinson Oct 12 '17 at 19:27

6 Answers6

3

An alternative where you never need to deal with floats, if efficiency is not your main concern:

x = []
for z in range(4, 100):
    for y in range(z):
        if z**2 - y**2 == 16:
            x.append(z)
Gerges
  • 6,269
  • 2
  • 22
  • 44
2

That is not your only problem.

Floating point numbers are not exact representations of all real numbers. In particular, they don't exactly represent numbers like square root two, and we can't even be sure that the floating point representation of a number like square root four will be exact.

There are at least two ways for a programmer to deal with this.

Solve that equation for y. There are three solutions, each of which depends on this.

solution kernel

Just three roots, I would say. But lovely, exact ones. Use the sympy library if you want to do it in this way.

An inexact way that allows for floating point approximation, and that is applicable where you cannot solve the original equation is this one.

tolerance is where the inexactitude comes in, being one's own estimate of how much difference one is willing to allow between an integer and a value that the square root routine produces. Notice that the abs operator must be applied so that the difference is treated as a positive value.

tolerance = 0.0001

x = []
for y in range(-100, 101):
    z = (16+y**2)**0.5
    if abs(z-round(z)) < tolerance:
        x.append(z)

print (x)

Result:

[5.0, 4.0, 5.0]
Bill Bell
  • 21,021
  • 5
  • 43
  • 58
1

Try the modulo operator:

def num():
    x= []
    for y in range (-100,100):
        z = (16+y**2)**0.5 
        if z % 1 == 0:
            x.append(z)
    return(x)

More info on modulo: How does % work in Python?

Stuart Buckingham
  • 1,574
  • 16
  • 25
0

Instead of if isinstance(z,int), you can just do if z==int(z). That will truncate anything to the right of the decimal and check whether the value has remained the same. Essentially just checking whether everything to the right of the decimal is zero.

mypetlion
  • 2,415
  • 5
  • 18
  • 22
0

If you are open to using SymPy, this problem can be stated as a diophantine equation z = sqrt(16+x**2) -> z**2 = 16 + x**2 where x and z must be integers:

>>> diophantine(16 + x**2 - y**2)
{(−3,−5),(−3,5),(0,−4),(0,4),(3,−5),(3,5)}

Those are your answers for x and y. So in this case, your "program" is just being able to state the problem in a form that can be solved with existing tools...at a relatively high level (vs the lower level you are working at right now).

smichr
  • 16,948
  • 2
  • 27
  • 34
0

If you consider only x from 0 to 100, you can compute the y value and take the int value. This will give you something that is either 1 less than the actual value or right on, so test both values to see if either satisfies the equivalent relationship, y**2 - (16 + x**2) = 0. If they do, then x is an answer (and so is -x):

>>> for x in range(0, 100):
...     arg = 16 + x**2
...     y1 = int(sqrt(arg))
...     if y1**2 == arg or (y1+1)**2 == arg:
...         if x == 0: print(x)
...         else: print(-x, x)
0
(-3, 3)

So by realizing that +/-x give the same result you need only search half the original range; realizing that you may be off by 1 when computing the sqrt doubles the tests that you do...but with a lot less need for insight and trickery. :-)

smichr
  • 16,948
  • 2
  • 27
  • 34