summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authordas <das@FreeBSD.org>2011-10-16 05:37:01 +0000
committerdas <das@FreeBSD.org>2011-10-16 05:37:01 +0000
commitb24da3b9e8c12123beb4e888883bb0ccd1a8a94a (patch)
tree7417f23eae5851fcc5edc7684fef4a862ec9a8b3 /lib
parent5bafe9f5deebb240191b7ed13ff9f18b044fb548 (diff)
downloadFreeBSD-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
Diffstat (limited to 'lib')
-rw-r--r--lib/msun/src/s_cexp.c7
-rw-r--r--lib/msun/src/s_cexpf.c4
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 */
OpenPOWER on IntegriCloud