Domanda

Vorrei utilizzare numeri complessi come definito nella C99, ma ho bisogno di sostenere i compilatori che non lo supportano (compilatori MS vengono in mente).

Non ho bisogno di molte funzioni, e l'attuazione delle funzioni necessarie su compilatori senza il supporto non è troppo difficile. Ma ho un momento difficile l'attuazione del 'tipo' se stesso. Idealmente, vorrei fare qualcosa di simile:

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

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

Ma io non sono sicuro di vedere come fare questo se il compilatore non può riconoscere 'complessa float'. Vorrei davvero credo che sia impossibile, ma la libreria C da Dinkumware sembra indicare il contrario. Qual'è la soluzione ? Non mi dispiace usando funzioni / macro per le operazioni sul tipo, ma ho bisogno di un modo per assegnare valori a un numero complesso, e tornare la sua parte reale / immaginaria in modo whichi è compatibile con C99.

Soluzione

ho finito per fare qualcosa di simile:

#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

per la definizione del tipo, e come segue per definire un insieme di funzioni complesse:

#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

Questo è un po 'complicato, ma questo mi permette di riutilizzare facilmente funzioni lib C quando disponibile, e può essere parzialmente automatizzato tramite generatore di codice.

È stato utile?

Soluzione

Non importa quello che fai, non si può fare "galleggiare complesso" analizza correttamente in un compilatore non-C99. Così, invece di scrivere che, fare alcune typedef. E 'molto più facile se si ha solo per sostenere un tipo complesso, quindi mi limiterò a dimostrare con i float complex.

In primo luogo, definire i tipi:

#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

Quindi, abbiamo bisogno di essere in grado di creare numeri complessi, e di emulare Creal e 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

In seguito, le funzioni di scrivere che l'aggiunta involucro, sottrazione, moltiplicazione, divisione, e confronti.

#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.

Si noti che add_complex(c, 5) non funziona nella modalità di C89 nel codice qui sopra, perché il compilatore non sa come fare 5 in un complesso. Questo è un problema difficile da risolvere in C senza il supporto del compilatore -. È necessario ricorrere a trucchi come i nuovi tgmath.h impieghi, che sono specifici per il compilatore

Purtroppo, l'effetto di tutto questo è che il bello della sintassi C99 come a+b per aggiungere numeri complessi deve essere scritto add_complex(a, b).

Un'altra opzione (come un altro poster ha sottolineato) è quello di utilizzare C ++ std::complex su compilatori non-C99. Questo potrebbe essere OK se si può avvolgere le cose in typedef e #ifdef s. Tuttavia, ci si richiede sia C ++ o C99.

Altri suggerimenti

C'è una libreria che ho trovato sul sito Web MSDN. Ecco un link. http://msdn.microsoft.com/en-us/library/0352zzhd. aspx

Mi auguro che aiuta.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top