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

后端 未结 6 1865
梦谈多话
梦谈多话 2021-01-13 13:15

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 li

相关标签:
6条回答
  • 2021-01-13 13:54

    We first calculate a candidate integer of the cubit root by a very rough rounding (int(... + 0.1)) then verify if it is really the cubic root or not with exact integer arithmetic. (I assumed n is an int)

    cand = int(n ** (1.0/3.0) + 0.1)
    if cand**3 == n:
        print(cand, "is the cube root of ", n)
        processing = False
    else:
        n -= 1
    
    0 讨论(0)
  • 2021-01-13 13:56

    Avoid any hacks with floats and tolerance levels, these are often unreliable for large inputs. A better tool for the job is to use a multiple precision arithmetic library such as gmpy2:

    >>> import gmpy2
    >>> root, exact = gmpy2.iroot(125, 3)
    >>> print(root)
    5
    >>> print(exact)
    True
    
    0 讨论(0)
  • 2021-01-13 14:02

    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    
    
    0 讨论(0)
  • 2021-01-13 14:07

    It's quite simple. Cast the floating point to a string and the string to a float. Like this

    float(str(pow(125, (1./3))))

    0 讨论(0)
  • 2021-01-13 14:09

    It's more straightforward to avoid the problem! For example:

    mx = 12000                   # maximum for cubes
    crmx = int(mx**(1/3)) + 1    # largest test integer
    
    result = max([n for n in range(crmx) if n**3 < mx])
    
    # result = 22
    

    Floating point arithmetic is always approximate. For example:

    .99999999999999999.is_integer() gives True

    .9999999999999999.is_integer() gives False

    (Your interpreter's mileage may differ.)

    0 讨论(0)
  • 2021-01-13 14:12

    The result of 125 ** (1.0/3.0) is never going to be an integer because that is a floating-point operation. This is much easier to do by looking at the cube instead. For instance, if you just want the largest number with an integer cube root below some number max, then you could:

    max = 12000
    cube_root = int(max ** (1.0/3.0))  # Take cube root and round to nearest integer
    cubed = cube_root ** 3             # Find cube of this number
    print str(cube_root) + " is the cube root of " + str(cubed)  # Output result
    

    The only sticking point for the above is if it happens to start the code with a max that is a cube root, and the cube root rounds to 4.9999999999999. When converted to an integer, this will round to 4, skipping the correct cube root (5) and going straight to "4 is the cube root of 64". You can get around this a few different ways. One way would be to convert the second line to:

    cube_root = int(max ** (1.0/3.0) + 0.5)
    

    This converts the "round down" operation of int() into a "round to nearest" operation.

    0 讨论(0)
提交回复
热议问题