为什么math.sqrt会导致ValueError: math domain error错误?

9
什么导致了这个问题?
from math import sqrt
print "a : "
a = float(raw_input())
print "b : "
b = float(raw_input())
print "c : "
c = float(raw_input())
d = (a + b + c)/2
s = sqrt(d*(d-a)*(d-b)*(d-c))
print("a+b+c =", a, b, c)
print("Distr. =", d*2, "Area =", s)

错误:

Traceback (most recent call last):
   File "C:/Python27/fájlok/háromszög terület2.py", line 11, in <module>
       s = sqrt(d*(d-a)*(d-b)*(d-c))
ValueError: math domain error

另请参阅:为什么math.log会导致ValueError:math domain error?,其中使用math.log的等效问题;Python math.acos函数使用时出现math domain error,其中使用math.acos的等效问题。


检查d*(d-a)(d-b)(d-c)的总和是否为正数,因为在数学中sqrt(-1)是复数,但在Python中不是。 - CY5
通常情况下,当您发布“为什么会出现这个错误?”时,请同时包含导致该错误的输入。 - Teepeemm
4个回答

8
问题在于海伦公式仅在两数之和大于第三个数时才成立。您需要明确检查这一点。
如果您正在使用代码进行操作,更好的方式是使用异常处理
try:
    s = sqrt(d*(d-a)*(d-b)*(d-c))
    print "a+b+c =", a, b, c
    print "Distr. =", d*2, "Area =", s
except ValueError:
    print "Please enter 3 valid sides"

如果您想在不使用try块的情况下完成此操作,可以这样做
delta = (d*(d-a)*(d-b)*(d-c))
if delta>0:
    s = sqrt(delta)
    print "a+b+c =", a, b, c
    print "Distr. =", d*2, "Area =", s
else:
    print "Please enter 3 valid sides"

谢谢您的回答,只是想说一句:我不能使用“del”作为变量。 - szzso24
哦,是的。这是一个保留字。谢谢。 - Bhargav Rao

7

sqrt在使用负数时会报错。 sqrt(-4) 报错是因为结果是一个复数

为此,您需要使用cmath

>>> from cmath import sqrt
>>> sqrt(-4)
2j
>>> sqrt(4)
(2+0j)

2

在我的代码中,我也遇到了同样的错误,直到我像aneroid建议的那样使用了cmath而不是math

import sys
import random
import cmath

x = random.randint(1, 100)
y = random.randint(1, 100)

a = 2 * x * cmath.sqrt(1 - x * 2 - y * 2)
b = 2 * cmath.sqrt(1 - x * 2 - y * 2)
c = 1 - 2 * (x * 2 + y * 2)

print ( 'The point on the sphere is: ', (a, b, c) )

我的代码这样运行得很好。


另一个答案已经建议使用 cmath 而不是 math - MSeifert
2
我可能错过了。我没有不给予适当的信誉的意图,而且我在Stackoverflow上也是新手[在个人资料方面]。对于我的新手倾向感到抱歉。 - SilverInternet

1
使用cmath代替。
import cmath
num=cmath.sqrt(your_number)
print(num)

现在无论数字是负数还是正数,您都将获得结果...

1
OP 正在尝试计算三角形的面积,似乎返回一个复杂值来表示未明确规定的三角形并不是一个好主意。 - Mark Dickinson
然后在输入值之前使用abs()确保该值为正数..... 然后使用math.sqrt().... - Subham Debnath
2
这还不如之前更糟糕!现在你默默地给出一个已知错误的问题答案,而不是给出任何提示表明有什么不对劲。如果有人问三角形边长为1、2和5的面积是多少,正确的答案既不是2.45j也不是2.45。正确的答案是要给出一些错误信息,比如“不存在这样的三角形”。 - Mark Dickinson
嗯......首先我们需要检查边是否符合勾股定理,然后再继续。 - Subham Debnath

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接