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.
This commit is contained in:
parent
5cb2685a59
commit
ad5e21e24b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=181374
@ -31,5 +31,6 @@
|
||||
double
|
||||
cimag(double complex z)
|
||||
{
|
||||
return -z * I;
|
||||
|
||||
return (__imag__ z);
|
||||
}
|
||||
|
@ -31,5 +31,6 @@
|
||||
float
|
||||
cimagf(float complex z)
|
||||
{
|
||||
return -z * I;
|
||||
|
||||
return (__imag__ z);
|
||||
}
|
||||
|
@ -31,5 +31,6 @@
|
||||
long double
|
||||
cimagl(long double complex z)
|
||||
{
|
||||
return -z * I;
|
||||
|
||||
return (__imag__ z);
|
||||
}
|
||||
|
@ -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)));
|
||||
}
|
||||
|
@ -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)));
|
||||
}
|
||||
|
@ -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)));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user