为什么我会得到ValueError:math域错误?

时间:2012-11-30 00:48:21

标签: python

我写了一个名为analyze_the_shape的函数,它接受一个2D顶点列表,这样列表就是2D欧几里德空间中顶点顺时针遍历的顺序。

我在解释器中调用它并将[(0, 0), (0, 4.0), (4.0, 4.0), (4.0, 0)]作为输入,但我得到ValueError : math domain error。我希望看到return ["SQUARE", 4.0]。我能做什么 ?

import math

def analyze_the_shape(liste):
    if len(liste) == 2 :
        d = ( (liste[1][0] - liste[0][0])**2 + (liste[1][1] - liste[0][1])**2 )**(0.5)   
        return ["LINESEGMENT", d ] 
    if len(liste) == 4 :
        d1 = abs(( (liste[1][0] - liste[0][0])**2 + (liste[1][1] - liste[0][1])**2 )**(0.5))
        d2 = abs(( (liste[2][0] - liste[1][0])**2 + (liste[2][1] - liste[1][1])**2 )**(0.5))
        d3 = abs(( (liste[3][0] - liste[2][0])**2 + (liste[3][1] - liste[2][1])**2 )**(0.5))
        d4 = abs(( (liste[0][0] - liste[3][0])**2 + (liste[0][1] - liste[3][1])**2 )**(0.5)) 
        hypo = abs(( (liste[2][1] - liste[0][1])**2 + (liste[2][0] - liste[0][0])**2 )**(0.5))
        cos_angle = float((hypo**2 - (d3)**2 + (d4)**2) / ((-2.0)*(d4)*(d3)))
        angle = math.degrees(math.acos(cos_angle))
        if d1 == d2 == d3 == d4 and abs(angle - 90.0) < 0.001 :
            return ["SQUARE", d1]  

这是我得到的错误:

>>> import a
>>> a.analyze_the_shape([(0, 0), (0, 4.0), (4.0, 4.0), (4.0, 0)])
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "a.py", line 15, in analyze_the_shape

ValueError: math domain error

4 个答案:

答案 0 :(得分:9)

此异常表示cos_angle不是math.acos的有效参数。

具体来说,在这个例子中,它刚好低于-1,这超出了acos的定义。

您可能会尝试强制在cos_angle内退回[-1,1],例如:

def clean_cos(cos_angle):
    return min(1,max(cos_angle,-1))

但是,这不会返回SQUARE,因为cos_angle或多或少等于示例中的-1,因此angle等于180。在异常之前计算可能存在问题。

答案 1 :(得分:2)

我遇到了同样的问题,事实证明@crld是对的。 我的输入值应该在[-1,1]范围内,但是......

print('{0:.32f}'.format(x))
>> 1.00000000000000022204460492503131

因此,作为一般规则,我建议将您提供的所有花车四舍五入math.acos

答案 2 :(得分:1)

当我运行你的代码时,我得到的堆栈跟踪是:

Traceback (most recent call last):
  File "md.py", line 22, in <module>
    analyze_the_shape([(0, 0), (0, 4.0), (4.0, 4.0), (4.0, 0)])
  File "md.py", line 18, in analyze_the_shape
    angle = math.degrees(math.acos(cos_angle))
ValueError: math domain error

我知道math.acos只接受-1.0 <= x <= 1.0之类的值。如果我在cos_angle < -1.0行之前打印angle = math.degrees(math.acos(cos_angle)),则会打印True。如果我打印出cos_angle,则会打印-1.0

我猜这里的问题是,Python存储cos_angle的方式并不完美,而且您为cos_angle生成的值仅略低于-1.0。< / p>

如果不是检查abs(angle - 90.0) < 0.001,而是检查了abs(cos_angle) < 0.001是否会更好。

修改

我认为你在这一行中有错误:

cos_angle = float((hypo**2 - (d3)**2 + (d4)**2) / ((-2.0)*(d4)*(d3)))

可能应该是:

cos_angle = float((hypo**2 - ((d3)**2 + (d4)**2)) / ((-2.0)*(d4)*(d3)))

请注意(d3)**2 + (d4)**2周围的额外情况。这样可以确保在之前完成添加hypo**2中减去该数量。

答案 3 :(得分:0)

尝试舍入cos_angle。我有同样的问题;在我的脚本中,math.acos(x)中x的值为-1.0000000000000002。为了解决这个问题,我只是将x的值四舍五入到六位小数,所以它出现了-1.0。