为什么我的Python代码未将明显平行的向量判定为平行?
问题原因分析
你遇到的问题根源是oracle函数的判定逻辑存在两处明显错误:
- 第一:判定条件优先级和逻辑完全错误,你设置的误差容忍规则完全没有生效
你写的触发break的条件为:
if s != scalar or (not s < (scalar + 0.001) and not s > (scalar -0.001))
这里的or逻辑意味着只要「s和scalar不完全相等」就会直接触发break,后续写的误差范围判断完全没有起到作用。
第二组向量[-1, -2]和[2,4]的比例值-0.5可以被浮点数精确存储,所以s == scalar成立,才能通过判定;而第一组向量的比例值是-1/3,属于无限循环小数,浮点数存储存在微小的精度误差,s != scalar直接触发break,自然不会判定为平行。
- 第二:误差判断的逻辑写反了,当前括号内的逻辑是「s不在[scalar-0.001, scalar+0.001]区间内」,即使去掉前面的
s != scalar,也会出现逻辑错误。 - 额外风险:你的代码没有判断向量元素是否为0,如果b向量中存在值为0的元素,会直接触发除零错误。
修复后的代码示例
推荐用点乘的方式判断平行,不需要做除法,能规避除零和部分浮点数精度问题:
import math from numpy import arccos, array, dot def oracle(a, b, eps=1e-3): if len(a) != len(b): print("两个向量长度不一致,无法判定") return mag_a = dot(a,a)**0.5 mag_b = dot(b,b)**0.5 # 点乘绝对值等于模长乘积即为平行 if abs(abs(dot(a,b)) - mag_a * mag_b) < eps: print("The two vectors are parallel.") def normalize2(a): mag_sq = dot(a, a) if mag_sq < 1e-6: print("The magnitude of this vector is 0 - it is a zero vector and so it has no direction.") return return mag_sq**0.5 def find_angle(a, b, eps=1e-3): c = dot(a, b) if abs(c) < eps: print("The two vectors are orthogonal.") mag_a = normalize2(a) mag_b = normalize2(b) if mag_a is None or mag_b is None: return # 避免arccos输入超出[-1,1]范围的数值问题 cos_theta = max(min(c/(mag_a * mag_b), 1.0), -1.0) theta = arccos(cos_theta) print(f"The angle, the shorter one, between the two vectors is {theta} radians or {math.degrees(theta)} degrees.") a = array([-7.5, -7.8]) print(a) b = array([22.5, 23.4]) print(b) find_angle(a, b) oracle(a, b) a = array([-1.0, -2.0]) print(a) b = array([2.0, 4.0]) print(b) find_angle(a, b) oracle(a, b)
运行效果
修复后两组向量都会被正确判定为平行,同时规避了浮点数精度、除零、反三角函数输入越界等潜在问题。
内容的提问来源于stack exchange,提问作者John Smith
相关产品推荐
相关产品推荐

