代码之家  ›  专栏  ›  技术社区  ›  David Cournapeau

配备visual studio的C99复杂支持

  •  6
  • David Cournapeau  · 技术社区  · 16 年前

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

    Dinkumware 似乎表明情况并非如此。解决方案是什么?我不介意使用函数/宏对类型进行操作,但我需要一种方法来为复数赋值,并以与C99兼容的方式返回其实部/虚部。

    #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
    

    #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
    

    2 回复  |  直到 13 年前
        1
  •  6
  •   Schwern    6 年前

    float complex .

    #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
    

    然后,我们需要能够创建复数,并模拟creal和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
    

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

    请注意 add_complex(c, 5) 在上述代码中,在C89模式下不起作用,因为编译器不知道如何将5变成复数。在没有编译器支持的情况下,这是一个在C中修复的棘手问题——你必须采用新的技巧 tgmath.h

    a+b add_complex(a, b) .

    另一种选择(正如另一位海报所指出的那样)是使用C++ std::complex 在非C99编译器上。如果你能用typedefs和 #ifdef 然而,你需要C++或C99。

        2
  •  -1
  •   mikeyickey    16 年前