Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I get a whole number as a result for a cube root?

Tags:

python

I am creating a problem which requires me to find the cube root of certain numbers, some of them have whole number roots, but a lot of them don't.

I have numbers like 125, that should return a cube root of 5 but instead Python returns 4.99999 Example:

>>> 125 ** (1.0/3.0)
4.999999999999999

This is my code:

processing = True
n = 12000
while processing:


    if (n ** (1.0/3.0)).is_integer() == True:
        print((n ** (1.0/3.0)), "is the cube root of ", n)
        processing = False
    else:
        n -= 1
like image 967
chopper draw lion4 Avatar asked Mar 21 '23 16:03

chopper draw lion4


1 Answers

The standard way to check for equality with floating point is to check for quality within a certain tolerance:

def floateq(a, b, tolerance=0.00000001):
    return abs(a-b) < tolerance

Now you can check if the rounded, converted-to-an-integer version of the cube root is equal to the cube root itself within a certain tolerance:

def has_integer_cube_root(n):
    floatroot = (n ** (1.0 / 3.0))
    introot = int(round(floatroot))
    return floateq(floatroot, introot)

Usage:

>>> has_integer_cube_root(125)
True
>>> has_integer_cube_root(126)
False

However, this is quite imprecise for your use case:

>>> has_integer_cube_root(40000**3)
True
>>> has_integer_cube_root(40000**3 + 1)
True

You can mess with the tolerance, but at some point, floating point numbers just won't be enough to have the accuracy you need.

EDIT: Yes, as the comment said, in this case you can check the result with integer arithmetic:

def has_integer_cube_root(n):
    floatroot = (n ** (1.0 / 3.0))
    introot = int(round(floatroot))
    return introot*introot*introot == n

>>> has_integer_cube_root(40000**3)
True
>>> has_integer_cube_root(40000**3 + 1)
False    
like image 134
Claudiu Avatar answered Apr 02 '23 19:04

Claudiu