diff options
author | das <das@FreeBSD.org> | 2008-08-07 14:39:56 +0000 |
---|---|---|
committer | das <das@FreeBSD.org> | 2008-08-07 14:39:56 +0000 |
commit | 1a05561e3440bd40c2aeaeb7b9369c3e0f3b5852 (patch) | |
tree | d63035ed872a363bf437b7f32c5b4dc4d50b47d4 /lib/msun/src | |
parent | f9ebb230ca1b1ab7963cd38728716b73299417dc (diff) | |
download | FreeBSD-src-1a05561e3440bd40c2aeaeb7b9369c3e0f3b5852.zip FreeBSD-src-1a05561e3440bd40c2aeaeb7b9369c3e0f3b5852.tar.gz |
Use cpack() and the gcc extension __imag__ to implement cimag() and
conj() instead of using expressions like z * I. The latter is bad for
several reasons:
1. It is implemented using arithmetic, which is unnecessary, and can
generate floating point exceptions, contrary to the requirements on
these functions.
2. gcc implements complex multiplication using a formula that breaks
down for infinities, e.g., it gives INFINITY * I == nan + inf I.
Diffstat (limited to 'lib/msun/src')
-rw-r--r-- | lib/msun/src/s_cimag.c | 3 | ||||
-rw-r--r-- | lib/msun/src/s_cimagf.c | 3 | ||||
-rw-r--r-- | lib/msun/src/s_cimagl.c | 3 | ||||
-rw-r--r-- | lib/msun/src/s_conj.c | 5 | ||||
-rw-r--r-- | lib/msun/src/s_conjf.c | 5 | ||||
-rw-r--r-- | lib/msun/src/s_conjl.c | 5 |
6 files changed, 18 insertions, 6 deletions
diff --git a/lib/msun/src/s_cimag.c b/lib/msun/src/s_cimag.c index 03ddf79..aa25423 100644 --- a/lib/msun/src/s_cimag.c +++ b/lib/msun/src/s_cimag.c @@ -31,5 +31,6 @@ double cimag(double complex z) { - return -z * I; + + return (__imag__ z); } diff --git a/lib/msun/src/s_cimagf.c b/lib/msun/src/s_cimagf.c index 6f943d8..6bd00d9 100644 --- a/lib/msun/src/s_cimagf.c +++ b/lib/msun/src/s_cimagf.c @@ -31,5 +31,6 @@ float cimagf(float complex z) { - return -z * I; + + return (__imag__ z); } diff --git a/lib/msun/src/s_cimagl.c b/lib/msun/src/s_cimagl.c index 7f531d0..581f443 100644 --- a/lib/msun/src/s_cimagl.c +++ b/lib/msun/src/s_cimagl.c @@ -31,5 +31,6 @@ long double cimagl(long double complex z) { - return -z * I; + + return (__imag__ z); } diff --git a/lib/msun/src/s_conj.c b/lib/msun/src/s_conj.c index 1d0011b..5770c29 100644 --- a/lib/msun/src/s_conj.c +++ b/lib/msun/src/s_conj.c @@ -28,8 +28,11 @@ #include <complex.h> +#include "math_private.h" + double complex conj(double complex z) { - return creal(z) - I * cimag(z); + + return (cpack(creal(z), -cimag(z))); } diff --git a/lib/msun/src/s_conjf.c b/lib/msun/src/s_conjf.c index ea951b9..b090760 100644 --- a/lib/msun/src/s_conjf.c +++ b/lib/msun/src/s_conjf.c @@ -28,8 +28,11 @@ #include <complex.h> +#include "math_private.h" + float complex conjf(float complex z) { - return crealf(z) - I * cimagf(z); + + return (cpackf(crealf(z), -cimagf(z))); } diff --git a/lib/msun/src/s_conjl.c b/lib/msun/src/s_conjl.c index e6cb2ef..0e431ef 100644 --- a/lib/msun/src/s_conjl.c +++ b/lib/msun/src/s_conjl.c @@ -28,8 +28,11 @@ #include <complex.h> +#include "math_private.h" + long double complex conjl(long double complex z) { - return creall(z) - I * cimagl(z); + + return (cpackl(creall(z), -cimagl(z))); } |