Visual Studio 的 C99 复杂支持
我想使用 C99 中定义的复数,但我需要支持不支持它的编译器(想到了 MS 编译器)。
我不需要很多功能,在没有支持的编译器上实现所需的功能并不太困难。 但我很难实现“类型”本身。 理想情况下,我想做类似的事情:
#ifndef HAVE_CREAL
double creal(complex z)
{
/* .... */
}
#endif
#ifndef HAVE_CREALF
float creal(float complex z)
{
/* ... */
}
#endif
但我不确定如果编译器无法识别“浮点复合体”,我不确定如何执行此操作。 我实际上认为这是不可能的,但 Dinkumware 的 C 库似乎表明不然。 解决办法是什么 ? 我不介意使用函数/宏对类型进行操作,但我需要一种方法将值分配给复数,并以与 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
这有点复杂,但这使我能够轻松地重用可用的 C lib 函数,并且可以通过以下方式部分自动化:代码生成器。
I would like to use complex numbers as defined in C99, but I need to support compilers which do not support it (MS compilers come to mind).
I don't need many functions, and implementing the needed functions on compilers without support is not too difficult. But I have a hard time implementing the 'type' itself. Ideally, I would like to do something like:
#ifndef HAVE_CREAL
double creal(complex z)
{
/* .... */
}
#endif
#ifndef HAVE_CREALF
float creal(float complex z)
{
/* ... */
}
#endif
But I am not sure I see how to do this if the compiler cannot recognize 'float complex'. I would actually think it is impossible, but the C library by Dinkumware seems to indicate otherwise. What is the solution ? I don't mind using functions/macros for operations on the type, but I need a way to assign values to a complex number, and get back its real/imaginary part in a way whichi is compatible with C99.
Solution
I ended up doing something like this:
#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
for the type definition, and as follows to define a set of complex functions:
#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
That's a bit complicated, but this enables me to easily reuse C lib functions when available, and it can be partly automated through code generator.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
无论您做什么,都无法在非 C99 编译器中正确解析“浮点数复杂”。 因此,不要编写这些内容,而是创建一些 typedef。 如果您只需要支持一种复杂类型,那就容易得多,因此我将仅使用
float complex
进行演示。首先,定义类型:
然后,我们需要能够创建复数,并模拟 creal 和 cimag。
接下来,编写包含加法、减法、乘法、除法和比较的函数。
请注意,上面代码中的
add_complex(c, 5)
在 C89 模式下不起作用,因为编译器不知道如何将 5 变成复数。 在没有编译器支持的情况下,这是一个在 C 中修复的棘手问题——您必须求助于新的 tgmath.h 使用之类的技巧,这些技巧是特定于编译器的。不幸的是,所有这些的结果是必须编写
add_complex(a, b)
等用于添加复数的 C99 语法(例如a+b
)。另一种选择(正如另一张海报所指出的)是在非 C99 编译器上使用 C++
std::complex
。 如果您可以将内容包装在 typedef 和#ifdef
中,这可能没问题。 但是,您需要 C++ 或 C99。No matter what you do, you can't make "float complex" parse properly in a non-C99 compiler. So instead of writing that, make some typedefs. It's far easier if you only have to support one complex type, so I'll just demonstrate with
float complex
.First, define the types:
Then, we need to be able to create complex numbers, and emulate creal and cimag.
Next, write functions that wrap addition, subtraction, multiplication, division, and comparisons.
Note that
add_complex(c, 5)
doesn't work in C89 mode in the above code, because the compiler doesn't know how to make 5 into a complex. This is a tricky problem to fix in C without compiler support -- you have to resort to tricks like the newtgmath.h
uses, which are compiler-specific.Unfortunately, the effect of all of this is that the nice C99 syntax like
a+b
to add complex numbers has to be writtenadd_complex(a, b)
.Another option (as another poster pointed to) is to use C++
std::complex
on non-C99 compilers. This might be OK if you can wrap things in typedefs and#ifdef
s. However, you'd require either C++ or C99.我在 msdn 网站上找到了一个库。 这是一个链接。
http://msdn.microsoft.com/en-us/library/0352zzhd。 aspx
我希望有帮助。
There is a library that I found on the msdn website. Here's a link.
http://msdn.microsoft.com/en-us/library/0352zzhd.aspx
I hope that helps.