返回复数的基本操作

Basic operations returning complex number

我在处理基本数学运算时遇到了一个有趣的意外行为,所以我写了这段简短的代码,希望它能很好地解释。

from collections import namedtuple

P = namedtuple('P', 'x y')

# euclidean distance with missing parentheses before sqroot
dist = lambda p1, p2:(p1.x-p2.x)**2 + (p1.y-p2.y)**2 ** 0.5
# correct_dist = lambda p1, p2: ((p1.x-p2.x)**2 + (p1.y-p2.y)**2)**0.5

A = P(0, 0)
B = P(1, 1)
AB = dist(A, B)

print(AB, type(AB))  # returns complex?!
print(-1**2 -1**2 **0.5)  # -2.0 (as expected since root not applied to the sum)

顺便说一句,这更多是为了理解目的(而不是为了实际使用)。
请帮助我更好地理解这一点!

你漏掉了一些括号。

(p1.x-p2.x) ** 2 + (p1.y-p2.y) ** 2 ** 0.5

应该是

((p1.x-p2.x) ** 2 + (p1.y-p2.y) ** 2) ** 0.5

然后你得到预期的 1.4142135623730951(而不是你写的 -2)。

括号是必需的,因为 **+ 具有更高的优先级。

解释这个结果的是运算顺序:

>>> 2 ** 2 ** 0.5
2.665144142690225
>>> 2 ** (2 ** 0.5)
2.665144142690225
>>> (2 ** 2) ** 0.5
2.0

在您的情况下,您得到 (0 - 1) ** (2 ** 0.5),这是将负数 (-1) 乘以无理数次幂 (sqrt(2)),因此得到复数输出。

我们可以看到:

>>> (0 - 1) ** (2 ** 0.5)                                                                                                                                      
(-0.26625534204141565-0.9639025328498773j)
>>> (-1) ** math.sqrt(2)
(-0.26625534204141565-0.9639025328498773j)

Python (**) 中的求幂运算符从 从右到左 分组。来自 Python Doc (Expressions):

Operators in the same box group left to right (except for exponentiation, which groups from right to left).

顺便说一下,你的台词:

print(-1**2 -1**2 **0.5)

产生 -2 因为它等同于:

print(-(1**2) - (1 ** (2 ** 0.5)))

你得到一个复数,因为你有一个负数 -1 被提升为一个无理数 (2**0.5),你在你的 dist 函数中有:

(-1)**(2**0.5)

您可以在此处阅读有关将负数提升为小数或无理数的更多信息: