You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Python变量负数平方异常:二分法求负数平方根问题排查

问题原因分析

嘿,这问题本质上是两个点:Python运算符优先级的误解,加上对「负数平方根」的数学逻辑认知偏差。

先说说你看到的奇怪现象:

  • 直接输入print(-12**2)得到-144,是因为Python里幂运算**的优先级比一元负号-高,所以实际计算的是-(12**2)——先算12的平方,再加负号。
  • 但当ans=-12.0时,ans**2其实是(-12.0)**2,这是数学上正确的负数平方运算,结果必然是144.0。你之前误以为这两种写法等价,其实运算顺序完全不同,这就是你预期和实际结果不符的核心原因。

再看你的二分逻辑:数学上,任何实数的平方都是非负数,所以当你输入x=-25时,在实数范围内根本不存在一个数ans,使得ans**2 = -25。你的代码里判断ans**2 < x(也就是某个非负数 < -25),这个条件永远不会成立,所以程序会一直把high设为ans,最后收敛到0附近,完全不符合你的预期。

解决方案

要支持负数的平方根求解,我们需要引入复数(因为负数的平方根是虚数)。修改思路很简单:先处理x的符号,对绝对值做二分查找得到实数平方根,再给结果加上虚数单位j

修改后的代码如下:

x = float(input("Enter a number, whose square root you want to find: "))
epsilon = 0.01
numGuesses = 0

# 处理负数情况,记录符号
is_negative = False
if x < 0:
    is_negative = True
    x = abs(x)

# 原有的二分查找逻辑,针对非负数
low = min(0.0, x)
high = max(1.0, x)
ans = (high + low)/2.0

while abs(ans**2 - x) >= epsilon:
    print("low =", low, "high =", high, "ans =", ans)
    numGuesses += 1
    if ans**2 < x:
        low = ans
    else:
        high = ans
    ans = (high + low)/2.0

# 根据原始符号返回结果
if is_negative:
    ans = complex(0, ans)
print("Number of guesses =", numGuesses)
print(ans, "is close to square root of", -x if is_negative else x)

测试输入-25的情况,程序会输出类似5j的结果,这就是-25的平方根(虚数解),完全符合数学定义。

如果你只是想在实数范围内处理(但负数本身没有实平方根),那可以在开头添加判断,提示用户输入非负数,避免无效的逻辑运算。

内容的提问来源于stack exchange,提问作者Pyth0n N00b

火山引擎 最新活动