这打印-2.4:
print(-3**0.8)
但这会打印一个虚数......?
a = -3
b = 0.8
print(a**b)
我无法弄清楚造成这种情况的原因,这个问题正在打破我的计划。如何使第二个语句输出与a
的正值和负值一致的一般情况下的第一个语句相同?
答案 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.0
或1.0
,具体取决于a
是否为否定,基本上应用了该符号。然后,无论a ** b
的符号如何,它都会乘以a
的结果。这将首先计算a ** b
忽略它的符号,然后根据需要应用该符号。这将摆脱差异。您可以使用math.copysign
:
>>> math.copysign(1, a) * (abs(a) ** b)
-2.4082246852806923
这只会将标记从a
复制到1
,这会根据消极情绪提供-1.0
或1.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))