Pregunta

Me gustaría utilizar números complejos como se define en el C99, pero tengo que apoyar a los compiladores que no lo soporten (compiladores MS vienen a la mente).

No necesito muchas funciones, y la implementación de las funciones necesarias en los compiladores y sin apoyo no es demasiado difícil. Pero tengo dificultades para implementar el 'tipo' en sí. Idealmente, me gustaría hacer algo como:

#ifndef HAVE_CREAL
double creal(complex z)
{
/* .... */
}
#endif

#ifndef HAVE_CREALF
float creal(float complex z)
{
/* ... */
}
#endif

Pero no estoy seguro de que veo cómo hacer esto si el compilador no puede reconocer 'complejo flotante'. De hecho, me parece que es imposible, pero la librería C Dinkumware parece indicar lo contrario. Cuál es la solución ? No me importa el uso de funciones / macros para las operaciones sobre el tipo, pero necesito una manera de asignar valores a un número complejo, y volver a su parte real / imaginario de una manera whichi es compatible con C99.

Solución

terminé haciendo algo como esto:

#ifdef USE_C99_COMPLEX
#include <complex.h>
typedef complex my_complex;
#else
typedef struct {
  double x, y;
} my_complex;
#endif

/*
 * Those unions are used to convert a pointer of my_complex to native C99
 * complex or our own complex type indenpendently on whether C99 complex
 * support is available
 */
#ifdef USE_C99_COMPLEX
typedef union {
    my_complex my_z;
    complex c99_z;
} __complex_to_c99_cast;
#else
typedef union {
    my_complex my_z;
    my_complex c99_z;
} __complex_to_c99_cast;
#endif

para la definición de tipo, y la siguiente manera para definir un conjunto de funciones complejas:

#ifndef HAVE_CREAL
double my_creal(my_complex z)
{
    union {
            my_complex z;
            double a[2];
    } z1;
    z1.z = z;
    return z1.a[0];
}
#endif

#ifdef HAVE_CREAL
my_complex my_creal(ny_complex z)
{
    __complex_to_c99_cast z1;
    __complex_to_c99_cast ret;

    z1.my_z = z;
    ret.c99_z = creal(z1.c99_z);
    return ret.npy_z;
}
#endif

Esto es un poco complicado, pero esto me permite volver a utilizar fácilmente las funciones lib C cuando esté disponible, y puede ser parcialmente automatizado a través de generador de código.

¿Fue útil?

Solución

No importa lo que hagas, no se puede hacer "flotar complejo" analiza correctamente en un compilador no C99. Así que en lugar de escribir esto, hacer algunas typedefs. Es mucho más fácil si usted sólo tiene que soportar un tipo complejo, así que voy a demostrar con float complex.

En primer lugar, definir los tipos:

#if __STDC_VERSION__ >= 199901L
//using a C99 compiler
#include &lt;complex.h>
typedef float _Complex float_complex;
#else
typedef struct 
{
    float re, im;
} float_complex;
#endif

A continuación, tenemos que ser capaces de crear los números complejos, y emular creal y Cimag.

#if __STDC_VERSION__ >= 199901L
//creal, cimag already defined in complex.h

inline complex_float make_complex_float(float real, float imag)
{
   return real + imag * I;
}
#else
#define creal(z) ((z).re)
#define cimag(z) ((z).im)

extern const complex_float complex_i; //put in a translation unit somewhere
#define I complex_i
inline complex_float make_complex_float(float real, float imag)
{
    complex_float z = {real, imag};
    return z;
}
#endif

A continuación, escribir funciones que la adición de envoltura, resta, multiplicación, división, y las comparaciones.

#if __STDC_VERSION__ >= 199901L
#define add_complex(a, b) ((a)+(b))
//similarly for other operations
#else //not C99
inline float_complex add_complex(float_complex a, float_complex b)
{
  float_complex z = {a.re + b.re, a.im + b.im};
  return z;
}
//similarly for subtract, multiply, divide, and comparison operations.

Tenga en cuenta que add_complex(c, 5) no funciona en el modo de C89 en el código anterior, debido a que el compilador no sabe cómo hacer 5 en un complejo. Este es un problema difícil de solucionar en C sin el apoyo del compilador -. Usted tiene que recurrir a trucos como los nuevos usos tgmath.h, que son su compilador

Por desgracia, el efecto de todo esto es que la sintaxis C99 agradable como a+b para agregar números complejos se debe escribir add_complex(a, b).

Otra opción (como otro cartel apuntó a) es el uso de C ++ std::complex en compiladores no C99. Esto podría estar bien si se puede envolver las cosas en typedefs y #ifdef s. Sin embargo, usted necesita ya sea C ++ o C99.

Otros consejos

Hay una biblioteca que he encontrado en el sitio web de MSDN. Aquí hay un enlace. http://msdn.microsoft.com/en-us/library/0352zzhd. aspx

Espero que ayude.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top