C99复杂支持与visual studio

我想使用C99中定义的复数,但我需要支持不支持它的编译器(MS编译器会浮现在脑海中)。

我不需要很多function,并且在没有支持的情况下在编译器上实现所需的function并不困难。 但我很难实现’类型’本身。 理想情况下,我想做的事情如下:

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

但是如果编译器无法识别’float complex’,我不确定如何做到这一点。 我实际上认为这是不可能的,但Dinkumware的C库似乎表明不是这样。 解决办法是什么 ? 我不介意使用函数/宏来对类型进行操作,但是我需要一种方法来为复数赋值,并以与C99兼容的方式返回其实/虚部分。

我最终做了这样的事情:

 #ifdef USE_C99_COMPLEX #include  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 

这有点复杂,但是这使我能够在可用时轻松地重用C lib函数,并且可以通过代码生成器部分自动化。

无论你做什么,你都不能在非C99编译器中正确地解析“浮动复杂”。 所以不要写那个,而是做一些typedef。 如果你只需要支持一个复杂的类型就容易得多,所以我只用float complex演示。

首先,定义类型:

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

然后,我们需要能够创建复杂的数字,并模拟creal和cimag。


如果STDC_VERSION > = 199901L

// creal,cimag已在complex.h中定义

inline complex_float make_complex_float(float real,float imag)
{
返回真实+想象*我;
}

其他

定义creal(z)((z).re)

define cimag(z)((z).im)

extern const complex_float complex_i; //在某处放入翻译单元

定义我complex_i

inline complex_float make_complex_float(float real,float imag)
{
complex_float z = {real,imag};
返回z;
}

万一

接下来,编写包含加法,减法,乘法,除法和比较的函数。

 #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`使用的技巧,这是特定于编译器的。

不幸的是,所有这一切的效果是,添加复数的好的C99语法如`a + b`必须写成`add_complex(a,b)`。

另一个选项(如另一张海报所指)是在非C99编译器上使用C ++`std :: complex`。 如果你可以在typedef和`#ifdef中包装东西,这可能没问题。 但是,您需要C ++或C99。

我在msdn网站上找到了一个库。 这是一个链接。 http://msdn.microsoft.com/en-us/library/0352zzhd.aspx

我希望有所帮助。