diff options
author | das <das@FreeBSD.org> | 2011-10-16 05:37:01 +0000 |
---|---|---|
committer | das <das@FreeBSD.org> | 2011-10-16 05:37:01 +0000 |
commit | b24da3b9e8c12123beb4e888883bb0ccd1a8a94a (patch) | |
tree | 7417f23eae5851fcc5edc7684fef4a862ec9a8b3 | |
parent | 5bafe9f5deebb240191b7ed13ff9f18b044fb548 (diff) | |
download | FreeBSD-src-b24da3b9e8c12123beb4e888883bb0ccd1a8a94a.zip FreeBSD-src-b24da3b9e8c12123beb4e888883bb0ccd1a8a94a.tar.gz |
Optimize the case of pure imaginary arguments. Calls like this are
common, e.g., in DFT implementations.
Discussed with: bde, kargl
-rw-r--r-- | lib/msun/src/s_cexp.c | 7 | ||||
-rw-r--r-- | lib/msun/src/s_cexpf.c | 4 |
2 files changed, 9 insertions, 2 deletions
diff --git a/lib/msun/src/s_cexp.c b/lib/msun/src/s_cexp.c index ecf0992..b907e1d 100644 --- a/lib/msun/src/s_cexp.c +++ b/lib/msun/src/s_cexp.c @@ -56,8 +56,12 @@ cexp(double complex z) /* cexp(x + I 0) = exp(x) + I 0 */ if ((hy | ly) == 0) return (cpack(exp(x), y)); + EXTRACT_WORDS(hx, lx, x); + /* cexp(0 + I y) = cos(y) + I sin(y) */ + if (((hx & 0x7fffffff) | lx) == 0) + return (cpack(cos(y), sin(y))); + if (hy >= 0x7ff00000) { - EXTRACT_WORDS(hx, lx, x); if (lx != 0 || (hx & 0x7fffffff) != 0x7ff00000) { /* cexp(finite|NaN +- I Inf|NaN) = NaN + I NaN */ return (cpack(y - y, y - y)); @@ -70,7 +74,6 @@ cexp(double complex z) } } - GET_HIGH_WORD(hx, x); if (hx >= exp_ovfl && hx <= cexp_ovfl) { /* * x is between 709.7 and 1454.3, so we must scale to avoid diff --git a/lib/msun/src/s_cexpf.c b/lib/msun/src/s_cexpf.c index 4ea3931..08ec545 100644 --- a/lib/msun/src/s_cexpf.c +++ b/lib/msun/src/s_cexpf.c @@ -57,6 +57,10 @@ cexpf(float complex z) if (hy == 0) return (cpackf(expf(x), y)); GET_FLOAT_WORD(hx, x); + /* cexp(0 + I y) = cos(y) + I sin(y) */ + if ((hx & 0x7fffffff) == 0) + return (cpackf(cosf(y), sinf(y))); + if (hy >= 0x7f800000) { if ((hx & 0x7fffffff) != 0x7f800000) { /* cexp(finite|NaN +- I Inf|NaN) = NaN + I NaN */ |