문제

C99에 정의 된대로 복소수를 사용하고 싶지만 지원하지 않는 컴파일러를 지원해야합니다 (MS 컴파일러가 떠 오릅니다).

많은 기능이 필요하지 않으며 지원없이 컴파일러에서 필요한 기능을 구현하는 것은 그리 어렵지 않습니다. 그러나 나는 '유형'자체를 구현하는 데 어려움을 겪고 있습니다. 이상적으로는 다음과 같은 일을하고 싶습니다.

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

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

그러나 컴파일러가 'float complex'를 인식 할 수 없다면이 작업을 수행하는 방법을 잘 모르겠습니다. 나는 실제로 그것이 불가능하다고 생각하지만 C 라이브러리는 Dinkumware 다른 것을 나타내는 것 같습니다. 해결책은 무엇인가 ? 유형의 작업에 Functions/Macros를 사용하는 것은 마음에 들지 않지만 값을 복소수로 할당하고 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 기능을 쉽게 재사용 할 수 있으며 코드 생성기를 통해 부분적으로 자동화 할 수 있습니다.

도움이 되었습니까?

해결책

당신이 무엇을하든 C99가 아닌 컴파일러에서 "플로트 콤플렉스"를 제대로 만들 수 없습니다. 따라서 글을 쓰지 않고 일부 타이핑을 만드십시오. 하나의 복잡한 유형 만 지원해야한다면 훨씬 쉽습니다. 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) 컴파일러는 5를 복합체로 만드는 방법을 모르기 때문에 위 코드에서 C89 모드에서 작동하지 않습니다. 이것은 컴파일러 지원없이 C에서 해결하기가 까다로운 문제입니다. 새로운 것과 같은 트릭에 의지해야합니다. tgmath.h 컴파일러-특이 적 인 용도.

불행히도,이 모든 것의 효과는 멋진 C99 구문이 a+b 복소수를 추가하려면 작성해야합니다 add_complex(a, b).

또 다른 옵션 (다른 포스터가 지적한 것처럼)은 C ++를 사용하는 것입니다. std::complex 비 C99 컴파일러에서. typedefs로 물건을 감을 수 있다면 괜찮을 것입니다. #ifdef에스. 그러나 C ++ 또는 C99가 필요합니다.

다른 팁

MSDN 웹 사이트에서 찾은 도서관이 있습니다. 여기 링크가 있습니다.http://msdn.microsoft.com/en-us/library/0352zzhd.aspx

도움이되기를 바랍니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top