随同hypot() [英] Companion to hypot()
问题描述
hypot
函数在该语言的1999年修订版中引入C中,以给定另一侧作为参数来计算直角三角形的斜边,但是要小心避免上溢/下溢,天真的实现会导致
The hypot
function, introduced into C in the 1999 revision of the language, calculates the hypotenuse of a right triangle given the other sides as arguments, but with care taken to avoid the over/underflow which would result from the naive implementation as
double hypot(double a, double b)
{
return sqrt(a*a + b*b);
}
我发现自己需要伴随功能:给定一个边和一个三角形的斜边,找到第三个边(避免出现下溢/溢出).我可以想到几种方法,但是想知道是否存在现有的最佳实践"?
I find myself with the need for companion functionality: given a side and the hypotenuse of a triangle, find the third side (avoiding under/overflow). I can think of a few ways to do this, but wondered if there was an existing "best practice"?
我的目标是Python,但实际上我正在寻找算法指针.
My target is Python, but really I'm looking for algorithm pointers.
感谢您的答复.如果有人对结果感兴趣,可以在此处和Python版本
Thanks for the replies. In case anyone is interested in the result, my C99 implementation can be found here and a Python version here, part of the Hypothesis project.
推荐答案
要做的第一件事是分解:
The first thing to do is factorize:
b = sqrt(h*h - a*a) = sqrt((h-a)*(h+a))
我们不仅避免了一些溢出,而且还获得了准确性.
如果有任何因素接近 1E + 154 = sqrt(1E + 308)
(IEEE 754 64位浮点数最多),那么我们还必须避免溢出:
We have not only avoided some overflow, but also gained accuracy.
If any factor is close to 1E+154 = sqrt(1E+308)
(max with IEEE 754 64 bits float) then we must also avoid overflow:
sqrt((h-a)*(h+a)) = sqrt(h-a) * sqrt(h+a)
这种情况不太可能发生,因此两个 sqrt
都是合理的,即使它比 sqrt
慢.
This case is very unlikely, so the two sqrt
's are justified, even if its slower than just a sqrt
.
请注意,如果 h〜5E + 7 * a
,则 h〜b
,这意味着没有足够的数字表示 b
与 h
不同.
Notice that if h ~ 5E+7 * a
then h ~ b
which means that there are not enough digits to represent b
as different from h
.
这篇关于随同hypot()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!