Commit 275aca8f authored by Ganesh Ajjanagadde's avatar Ganesh Ajjanagadde

configure+libm.h: add hypot emulation

It is known that the naive sqrt(x*x + y*y) approach for computing the
hypotenuse suffers from overflow and accuracy issues, see e.g
http://www.johndcook.com/blog/2010/06/02/whats-so-hard-about-finding-a-hypotenuse/.
This adds hypot support to FFmpeg, a C99 function.

On platforms without hypot, this patch does a reaonable workaround, that
although not as accurate as GNU libm, is readable and does not suffer
from the overflow issue. Improvements can be made separately.
Reviewed-by: 's avatarMichael Niedermayer <michael@niedermayer.cc>
Signed-off-by: 's avatarGanesh Ajjanagadde <gajjanagadde@gmail.com>
parent 14ea4151
......@@ -1773,6 +1773,7 @@ MATH_FUNCS="
exp2
exp2f
expf
hypot
isinf
isnan
ldexpf
......@@ -5308,6 +5309,7 @@ disabled crystalhd || check_lib libcrystalhd/libcrystalhd_if.h DtsCrystalHDVersi
atan2f_args=2
copysign_args=2
hypot_args=2
ldexpf_args=2
powf_args=2
......
......@@ -132,6 +132,29 @@ static av_always_inline av_const int avpriv_isnan(double x)
: avpriv_isnan(x))
#endif /* HAVE_ISNAN */
#if !HAVE_HYPOT
#undef hypot
static inline av_const double hypot(double x, double y)
{
double ret, temp;
x = fabs(x);
y = fabs(y);
if (isinf(x) || isinf(y))
return av_int2double(0x7ff0000000000000);
if (x == 0 || y == 0)
return x + y;
if (x < y) {
temp = x;
x = y;
y = temp;
}
y = y/x;
return x*sqrt(1 + y*y);
}
#endif /* HAVE_HYPOT */
#if !HAVE_LDEXPF
#undef ldexpf
#define ldexpf(x, exp) ((float)ldexp(x, exp))
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment