内置双星号电源功能无法正常工作

时间:2017-07-09 02:58:52

标签: python python-3.x

这打印-2.4:

print(-3**0.8)

但这会打印一个虚数......?

a = -3
b = 0.8
print(a**b)

我无法弄清楚造成这种情况的原因,这个问题正在打破我的计划。如何使第二个语句输出与a的正值和负值一致的一般情况下的第一个语句相同?

3 个答案:

答案 0 :(得分:6)

the Python 3.6 documentation

  

6.5。电力运营商

     

权力运算符比左边的一元运算符绑定得更紧密;它比右边的一元运算符更紧密。语法是:

power ::=  ( await_expr | primary ) ["**" u_expr]
     

因此,在功率和一元运算符的未加密集的序列中,运算符从右到左进行求值(这不会限制操作数的求值顺序):-1**2得到-1。< / p>

因此,在第一个例子中:

>>> -3 ** 0.8
-2.4082246852806923

评估从右到左,因为**的优先级高于一元-,绑定更严格 - 所以这里首先评估3 ** 0.8,然后是一元-运算符应用于负值。但是,在第二个示例中,表达式等效(-3) ** 0.8,因为-3存储在名称中,评估结果是一个虚数:

>>> a = -3
>>> b = 0.8
>>> a ** b
(-1.9482946966653392+1.4155189542146738j)

解决方案是在没有一元运算符的情况下计算结果,然后根据需要应用符号,每Shakar Bhattarai's answer

>>> int(a / abs(a)) * (abs(a) ** b)
-2.4082246852806923

第一部分int(a / abs(a))评估为-1.01.0,具体取决于a是否为否定,基本上应用了该符号。然后,无论a ** b的符号如何,它都会乘以a的结果。这将首先计算a ** b忽略它的符号,然后根据需要应用该符号。这将摆脱差异。您可以使用math.copysign

应用相同的概念
>>> math.copysign(1, a) * (abs(a) ** b)
-2.4082246852806923

这只会将标记从a复制到1,这会根据消极情绪提供-1.01.0

答案 1 :(得分:3)

这是因为电力运营商的优先权。电力运营商比一元运营商更严格。所以:

-3 ** 0.8

评估为

-(3 * 0.8)

您可以看到Python如何使用ast模块解析您的代码:

>>> import ast
>>> ast.dump(ast.parse('-3 ** 0.8'))
'Module(body=[Expr(value=UnaryOp(op=USub(), operand=BinOp(left=Num(n=3), op=Pow(), right=Num(n=0.8))))])'
>>> 

在上文中,3 ** 0.8被视为一个表达式,其中**是运算符。然后将一元减号应用于内部表达式的值。

但是,在第二个示例中,值存储在变量中,因此优先级不会影响表达式。因此a ** b(-3) ** 0.8

相当

解决方案是使用括号将一元减号绑定到三:

>>> (-3) ** 0.8
(-1.94829469666534+1.4155189542146727j)
>>> 

答案 2 :(得分:1)

**运算符的优先级高于所有其他运算符。因此,当你使用

print(-3**0.8)

python首先评估指数,然后否定它。

但是当你跑步时

a = -3
b = 0.8
print(a**b)

a首先被隐含地否定了。因此,结果实际上是一个虚数(负数增加到分数指数)

要解决您的问题,您可以执行类似

的操作
 print (int(a/abs(a))*(abs(a)**b))