素材牛VIP会员
python 开立方问题
 zh***ni  分类:Python  人气:1016  回帖:2  发布于6年前 收藏
temp
Out[53]: -0.7037246201969727

type(temp)
Out[54]: float

type(-0.7037246201969727)
Out[55]: float

temp**(1.0/3)
Out[56]: (0.4447380144139145+0.7703088370221993j)

-0.7037246201969727**(1.0/3)
Out[57]: -0.8894760288278287

1、如图,为什么temp(1.0/3)求出来的结果是复数,而-0.7037246201969727(1.0/3)求出来的结果没有问题。该怎么解决
2、如果用算术库的话该怎么写呢,用math.pow()总是报错,求帮忙解决

 标签:python

讨论这个帖子(2)垃圾回帖将一律封号处理……

Lv1 新人
海***人 Web前端工程师 6年前#1

这是一个数学问题,只不过Python原生支持复数罢了。
从复分析上来讲,开方运算本来就是一个多值函数。
以你给出的temp为例,因为是开三次方,所以有三个根,一个实根,两个共轭复根:

-0.8894760288278287
0.4447380144139145+0.7703088370221993j
0.4447380144139145-0.7703088370221993j

直角坐标可能看不明白这三个值的关系,让我们表示成极坐标形式:

0.8894760288278287∠π
0.8894760288278287∠π/3
0.8894760288278287∠5π/3

很容易看出,这三个根的关系是:模相等,幅角分别相差2π/3。

经过上面的一番观察,可以发现,实根可以直接用任意复根的模(或模的相反数)表示。
用Python标准库来表示这个过程,就是这样的:

import math

temp = -0.7037246201969727

complex_root = temp ** (1.0/3)            # 结果可能是复根
modulus = abs(complex_root)               # 取模
real_root = math.copysign(modulus, temp)  # 实根的正负与原数相同,绝对值与复根的模相同
Lv4 码徒
朱***叶 UI设计师 6年前#2

非常棒的问题!

之前一直没注意,试了一下发现的确是这样的

事是上我用python2.x它会直接报错,估计题主用的是3.x

想了一下,我觉得是这样:

  • 计算机中浮点数储存皆有精度限制,1/3算完后temp实为0.33333333333333再换成十进制后分母为偶数,因此样例56开出来为复数

  • 至于样例57则是优先级问题,**比-优先级高,因此先作幂运算再取负,即为正确答案

至于说到正确做法,如果图方便就判断一下符号再开方,或者可以用诸如numpy这样的数学库

附上歪果仁的讨论帖: http://stackoverflow.com/questions/1361740/cubic-root-of-the-negative-number-on-python

 文明上网,理性发言!   😉 阿里云幸运券,戳我领取