如何使用Python找到立方根?

45

以下是我发现的最佳方法:

x = int(raw_input("Enter an integer: "))
for ans in range(0, abs(x) + 1):
    if ans ** 3 == abs(x):
        break
if ans ** 3 != abs(x):
    print x, 'is not a perfect cube!'
else:
    if x < 0:
        ans = -ans
    print 'Cube root of ' + str(x) + ' is ' + str(ans)

有没有更好的方法,最好是避免迭代候选值的方法?


3
自从Python 3.11发布以来已经过去了几个月,您只需使用math.cbrt(x),在先导入import math后即可。它还将覆盖负值情况,并且比x ** (1/3)更加优化。 - Mortasen
3个回答

58

你可以使用x ** (1. / 3)来计算x的(浮点数)立方根。

这里稍微有点微妙的是,这在Python 2和3中对负数的处理方式不同。然而,下面的代码可以处理这个问题:

def is_perfect_cube(x):
    x = abs(x)
    return int(round(x ** (1. / 3))) ** 3 == x

print(is_perfect_cube(63))
print(is_perfect_cube(64))
print(is_perfect_cube(65))
print(is_perfect_cube(-63))
print(is_perfect_cube(-64))
print(is_perfect_cube(-65))
print(is_perfect_cube(2146689000)) # no other currently posted solution
                                   # handles this correctly

这个代码会对x进行立方根运算,四舍五入取整,然后将结果三次方,最终检查是否等于x

取绝对值的原因是为了让代码在Python版本中正确处理负数(Python 2和3以不同方式处理负数的分数幂)。


2
@PascalvKooten:这段代码需要四舍五入到最近的整数,而 int() 函数是向零舍入的。 - NPE
2
抱歉,你是对的。 - vaultah
2
@PascalvKooten:请在这场辩论中付出一些努力,不要只是向其他人轰炸随机问题。:) 我的答案中没有一个测试用例可以在没有round()的情况下工作。 - NPE
6
“Erm,0.3333333333333333仍然不等于数学上的三分之一,因此立方根仍然是近似值。就像我说的那样,与其猜测,还不如直接通过试验代码。” - NPE
2
它在10**45时失败,而"基于二分搜索的答案有效" - jfs
显示剩余13条评论

33

最好的方法是使用简单的数学。

>>> a = 8
>>> a**(1./3.)
2.0

编辑

针对负数:

>>> a = -8
>>> -(-a)**(1./3.)
-2.0

按照规定,满足所有要求的完整程序

x = int(input("Enter an integer: "))
if x>0:
    ans = x**(1./3.)
    if ans ** 3 != abs(x):
        print x, 'is not a perfect cube!'
else:
    ans = -((-x)**(1./3.))
    if ans ** 3 != -abs(x):
        print x, 'is not a perfect cube!'

print 'Cube root of ' + str(x) + ' is ' + str(ans)

如果a=-8,它会给出奇怪的输出。矿山数字将给您复数输出。这是-8的立方根等于-2。这里是输出:(1.0000000000000002+1.7320508075688772j)。它是一个复数。 - user4466285
1
那个奇怪的复数,在技术上是正确的。 - M4rtini
3
整个程序有漏洞。例如,它无法正确处理2146689000(说它不是完全立方数)。 - NPE
729.0**(1./3.) 8.999999999999998 - x4444
请使用Python3代码,而不是Python2。 - x4444
显示剩余5条评论

9
def cube(x):
    if 0<=x: return x**(1./3.)
    return -(-x)**(1./3.)
print (cube(8))
print (cube(-8))

以下是针对正数和负数的完整答案。

>>> 
2.0
-2.0
>>> 

或者这里有一个一行代码;

root_cube = lambda x: x**(1./3.) if 0<=x else -(-x)**(1./3.)

729.0**(1./3.) 8.999999999999998 - x4444

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接