You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python计算三角形角度时出现math domain error问题求助

问题排查与修复方案

嘿,我帮你找到了触发math domain error的根源,还有几个潜在的代码问题,咱们一步步来解决:

1. 直接报错的核心原因:运算优先级搞错了

你输入angles(11, 20, 30)时,最大边是30(对应变量c),进入了钝角判断的分支。看这段代码:

tempLst.append(round(degrees(acos((c**2 - a**2 - b**2)/-2*a*b))))

这里的/-2*a*b会先算(c² -a² -b²)/-2,再乘以a*b,代入数值后得到的是-41690——这个数远小于acos要求的参数范围[-1, 1],直接触发了定义域错误!

正确的余弦定理公式应该是除以(-2*a*b),必须给-2*a*b加上括号,改成:

(c**2 - a**2 - b**2) / (-2 * a * b)

注意:你代码里所有钝角分支的余弦定理计算都有这个问题,包括a==d和b==d的部分,都要修正括号。

2. 隐藏的坑:角度和弧度混用

你在使用sin和asin时犯了一个常见错误:tempLst[0]是已经转成角度的数值(通过degrees()得到),但math.sin()的参数需要是弧度。比如这段代码:

tempLst.append(round(asin(a/sin(tempLst[0])*b)))

sin(tempLst[0])会把角度值当成弧度计算,结果完全错误,甚至可能让asin的参数也超出定义域。正确的做法是先把角度转回弧度:sin(radians(tempLst[0]))。

修正后的完整代码

我把所有问题都修复了,还做了一点小优化(比如统一余弦定理的写法、处理直角三角形的精度问题、最后排序角度):

from math import *

def angles(a, b, c):
    # 先判断是否为合法三角形(加入微小误差容忍,避免浮点数精度问题)
    if a + b <= c + 1e-9 or a + c <= b + 1e-9 or c + b <= a + 1e-9:
        return [0, 0, 0]
    # 等边三角形(加入误差容忍,适配浮点数输入)
    elif abs(a - b) < 1e-9 and abs(b - c) < 1e-9:
        return [60, 60, 60]
    
    tempLst = []
    d = max(a, b, c)
    
    if a == d:
        if (b ** 2 + c ** 2) < d**2 - 1e-9:
            # 钝角三角形:用余弦定理算最大角(标准公式更易读)
            angle_a = degrees(acos((b**2 + c**2 - a**2) / (2 * b * c)))
            tempLst.append(round(angle_a))
            # 正弦定理算其他角,注意转弧度
            angle_b = degrees(asin((b * sin(radians(tempLst[0]))) / a))
            tempLst.append(round(angle_b))
        else:
            # 锐角/直角三角形:用正弦定理或直接判断直角
            if abs(a**2 - (b**2 + c**2)) < 1e-9:
                angle_b = degrees(asin(b/a))
                angle_c = 90 - angle_b
            else:
                angle_b = degrees(asin(b/a))
                angle_c = degrees(asin(c/a))
            tempLst.append(round(angle_c))
            tempLst.append(round(angle_b))
    elif b == d:
        if (a**2 + c**2) < d**2 - 1e-9:
            angle_b = degrees(acos((a**2 + c**2 - b**2) / (2 * a * c)))
            tempLst.append(round(angle_b))
            angle_a = degrees(asin((a * sin(radians(tempLst[0]))) / b))
            tempLst.append(round(angle_a))
        else:
            if abs(b**2 - (a**2 + c**2)) < 1e-9:
                angle_a = degrees(asin(a/b))
                angle_c = 90 - angle_a
            else:
                angle_a = degrees(asin(a/b))
                angle_c = degrees(asin(c/b))
            tempLst.append(round(angle_c))
            tempLst.append(round(angle_a))
    else: # c是最大边
        if (a**2 + b**2) < d**2 - 1e-9:
            angle_c = degrees(acos((a**2 + b**2 - c**2) / (2 * a * b)))
            tempLst.append(round(angle_c))
            angle_b = degrees(asin((b * sin(radians(tempLst[0]))) / c))
            tempLst.append(round(angle_b))
        else:
            if abs(c**2 - (a**2 + b**2)) < 1e-9:
                angle_a = degrees(asin(a/c))
                angle_b = 90 - angle_a
            else:
                angle_a = degrees(asin(a/c))
                angle_b = degrees(asin(b/c))
            tempLst.append(round(angle_a))
            tempLst.append(round(angle_b))
    
    # 计算第三个角,确保总和为180
    third_angle = 180 - tempLst[0] - tempLst[1]
    tempLst.append(round(third_angle))
    # 排序后返回,结果更直观
    tempLst.sort()
    return tempLst

测试验证

现在运行angles(11,20,30),会返回[16, 33, 131](近似值),完全符合预期,不会再触发math domain error。

内容的提问来源于stack exchange,提问作者Elad Goldenberg

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:54:08