Frage

Ich mag komplexe Zahlen verwenden, wie in C99 definiert, aber ich brauche Compiler zu unterstützen, die nicht unterstützen, sie (MS Compiler in dem Sinne kommen).

Ich brauche nicht viele Funktionen, und auf Compiler ohne Unterstützung die benötigten Funktionen der Umsetzung ist nicht allzu schwierig. Aber ich habe eine harte Zeit, die Umsetzung der ‚Typ‘ selbst. Im Idealfall würde Ich mag so etwas wie tun:

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

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

Aber ich bin nicht sicher, ich sehe, wie dies zu tun, wenn der Compiler nicht ‚float-Komplex‘ erkennen kann. Ich würde denken, eigentlich ist es unmöglich, aber die C-Bibliothek von Dinkumware scheint anders anzuzeigen. Was ist die Lösung ? Ich bin nicht dagegen Funktionen / Makros für Operationen an der Art, aber ich brauche eine Möglichkeit, Werte zu einer komplexen Zahl zuweisen, und erhalten ihre real / imaginären Teil in einer Art und Weise zurück whichi mit C99 kompatibel ist.

Lösung

ich am Ende so etwas wie dies zu tun:

#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

für die Typ-Definition und wie folgt eine Reihe von komplexen Funktionen zu definieren:

#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

Das ist ein bisschen kompliziert, aber dies ermöglicht es mich leicht Funktionen C lib wieder zu verwenden, wenn verfügbar, und es kann teilweise durch Code-Generator automatisiert werden.

War es hilfreich?

Lösung

Egal, was Sie tun, können Sie nicht „float-Komplex“ analysiert ordnungsgemäß in einem Nicht-C99-Compiler machen. Anstatt also, dass zu schreiben, einige typedefs machen. Es ist viel einfacher, wenn Sie nur einen komplexen Typ zu unterstützen haben, also werde ich nur mit float complex demonstrieren.

Zunächst definieren die Typen:

#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

Dann müssen wir komplexe Zahlen erstellen zu können, und emulieren creal und 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

Als nächstes schreiben Funktionen, die Wrap-Addition, Subtraktion, Multiplikation, Division und Vergleiche.

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

Beachten Sie, dass add_complex(c, 5) nicht in dem obigen Code in C89-Modus nicht funktioniert, weil der Compiler nicht weiß, wie 5 in einen Komplex zu machen. Dies ist ein heikles Problem in C zu beheben, ohne Compiler-Unterstützung -. Sie Tricks, wie die neuen tgmath.h Anwendungen zurückgreifen müssen, die Compiler-spezifisch sind,

Leider ist die Wirkung von all dem ist, dass die nette C99 Syntax wie a+b komplexe Zahlen zu addieren hat geschrieben add_complex(a, b) werden.

Eine andere Möglichkeit (als ein weiteres Plakat zeigte auf) C ++ std::complex auf Nicht-C99-Compiler zu verwenden. Dies könnte in Ordnung sein, wenn Sie die Dinge in typedefs und #ifdefs wickeln können. Allerdings würde man entweder C ++ oder C99 erfordern.

Andere Tipps

Es gibt eine Bibliothek, die ich auf der MSDN-Website zu finden. Hier ist ein Link. http://msdn.microsoft.com/en-us/library/0352zzhd. aspx

Ich hoffe, das hilft.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top