0

Recently I encountered a problem:

I want to calculate various roots of various numbers like this:

x = x ** 1/y+1 

None of the methods I know result in a working code.

Method 1:

x = 54 y = 2 x = x ** 1/y+1 print(x) 

Printed value is 28.0 instead of 3.7798

Method 2:

x = 54 y = 2 x = x ** 1/(y+1) print(x) 

Printed value is 18.0 istead of 3.7798

Method 3:

x = 216 y = 2 x = x ** (1/(y+1)) print(x) 

Printed value is 5.99 instead of 6

Is there a way that would work with y being up to 20?

Edit:

Another suggested method:

def nth_root(val, n): ret = int(val**(1./n)) return ret + 1 if (ret + 1) ** n == val else ret y = 1 print(nth_root(19, (y+1))) 

prints 4

5
  • 1
    for starters, docs.python.org/3/reference/… Commented Jan 27, 2016 at 0:22
  • You should look up "operator precedence" for Python, which would indicate that you need the parentheses as shown in your 3rd attempt. As far as the 5.99 answer is concerned, I did not get that when I tried your example. I suspect there's more context to your scenario than you've described. Commented Jan 27, 2016 at 0:23
  • also, third example gives 6.0. Commented Jan 27, 2016 at 0:24
  • @njzk2 I get 5.999999999999999 in 3.4. Commented Jan 27, 2016 at 0:26
  • 5.999999999999999 in 3.5 too. I thought 3.x had the intelligent repr thing? Commented Jan 27, 2016 at 0:27

5 Answers 5

3

Since everyone else has already told you why your Method 3 is correct, I'll stick to getting you an accurate answer. You can read more about why you're not getting exactly 6, but basically it's because your computer doesn't represent the 1/3 exactly when doing the calculation and makes the final answer off.

So, the easiest solution is to use sympy:

import sympy y = 216 x = 2 x = sympy.root(y,x+1) print(x) 
Sign up to request clarification or add additional context in comments.

Comments

3

You don't seem to understand (yet) order of operations in a programming language. You need parentheses to make sure you add 1 to y, then take the reciprocal, and then use that as an exponent. The "natural" order is the opposite.

x = x ** (1.0/(y+1)) 

7 Comments

Well, no ... it must have been Python 3, in which division is floating point by default. Or the result would have been different.
x = 216 y = 2 x = x ** (1.0/(y+1)) print(x) still prints 5.9999
@Tom Zych: thanks; I've updated the answer.
There has to be something I'm missing... My last method looks exactly like yours just with .0 added. Even if I add the .0, I still get 5.99 printed. So is it that ,,I don't seem to understand'' or your way doesn't solve my problem either?
@MantasKandratavicius use this method.
|
2

What you want is this (assuming you are using Python 3):

x = x ** (1/(y+1)) 

For Python 2, either of the following will work:

from __future__ import division x = x ** (1/(y+1)) 

or (also fine on Python 3):

x = x ** (1.0/(y+1)) 

The issue is you need to apply the parentheses in the correct locations to get the order of operations right.

Method 3 is to do with floating point arithmetic. See: https://docs.python.org/3.5/tutorial/floatingpoint.html

For more info on Python 2 vs. Python 3 division: Division in Python 2.7. and 3.3

4 Comments

if the OP were using python 2, their 3rd example would ouptut 1, not 5.99
Correct. My solutions take that in to account. I will update the solution to clarify the logic errors in the OP's code too.
my point being that the op is not using python 2, which your solution assumes
Point taken. I'll edit the Python 2 part as reference only.
0

Only your last code works because ** has higher precedence than / (and / has higher precendence than +).

The value is not exactly 6, because floating point numbers are not perfectly accurate. A third can not be represented as a float.

Comments

0

All your values are just as expected. According to the python operator precedence:

x ** 1/y+1 is parsed as ((x ** 1) / y) + 1, and

x ** 1/(y+1) is actually (x ** 1) / (y + 1).

What you probably want is x ** (1. / (y + 1)). Note, that 1. is a floating point number, causing the whole expression to be evaluated as floats. This also means that you will work with finite precision, e.g., getting 5.99999 instead fo 6 is to be expected.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.