hypot
函数在 1999 年的 C 语言修订版中引入,计算直角三角形的斜边,给定其他边作为参数,但要注意避免上溢/下溢将导致天真的实现为
double hypot(double a, double b)
{
return sqrt(a*a + b*b);
}
我发现自己需要配套功能:给定三角形的一条边和斜边,找到第三条边(避免溢出/溢出)。我可以想到几种方法来做到这一点,但想知道是否有现成的“最佳实践”?
我的目标是 Python,但实际上我正在寻找算法指针。
感谢您的回复。如果有人对结果感兴趣,可以找到我的 C99 实现 here和一个 Python 版本 here , 的一部分 Hypothesis项目。
最佳答案
首先要做的是因式分解:
b = sqrt(h*h - a*a) = sqrt((h-a)*(h+a))
我们不仅避免了一些溢出,而且还获得了准确性。
如果任何因子接近于 1E+154 = sqrt(1E+308)
(最大 IEEE 754 64 位 float ),那么我们还必须避免溢出:
sqrt((h-a)*(h+a)) = sqrt(h-a) * sqrt(h+a)
这种情况不太可能发生,所以两个 sqrt
是合理的,即使它比一个 sqrt
慢。
注意如果 h ~ 5E+7 * a
那么 h ~ b
这意味着没有足够的数字来表示 b
与 h
不同。
关于hypot() 的伴侣,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49191477/