如何在 C 中转换复数 double
How to cast complex double in C
我在第 3 方库中调用 C 函数,return 使用自定义类型的复数:
typedef struct
{
double dat[2];
} complex_num;
这里dat[0]是实部,dat[1]是虚部。我想安全且可移植地将它们转换为 C complex double
类型以使用优化的数学运算,如 add/multiply 等。假设我有一个函数 returning complex_num
:
complex_num dostuff(...);
我的问题是,我可以安全地执行以下操作吗:
complex double a = (complex double) dostuff(...);
数组 padding/alignments 是否有任何问题会搞砸上面的转换?
来自https://en.cppreference.com/w/c/language/arithmetic_types#Complex_floating_types:
Each complex type has the same object representation and alignment requirements as an array of two elements of the corresponding real type (float
for float complex
, double
for double complex
, long double
for long double complex
). The first element of the array holds the real part, and the second element of the array holds the imaginary component.
所以,这样写是完全有效的:
complex double a;
{
complex_num a_ = dostuff(...);
memcpy(&a, &a_, sizeof(a));
}
自己写一个转换函数:
complex double MyCast(complex_num x) { return CMPLX(x.dat[0], x.dat[1]); }
CMPLX
是一个标准的宏,定义在<complex.h>
中。带有 clang-1001.0.46.4 和 GCC 9.1 的 Apple LLVM 10.0.1 将 CMPLX
的这种使用优化为无操作,至少在我测试的一种情况下是这样。
我在第 3 方库中调用 C 函数,return 使用自定义类型的复数:
typedef struct
{
double dat[2];
} complex_num;
这里dat[0]是实部,dat[1]是虚部。我想安全且可移植地将它们转换为 C complex double
类型以使用优化的数学运算,如 add/multiply 等。假设我有一个函数 returning complex_num
:
complex_num dostuff(...);
我的问题是,我可以安全地执行以下操作吗:
complex double a = (complex double) dostuff(...);
数组 padding/alignments 是否有任何问题会搞砸上面的转换?
来自https://en.cppreference.com/w/c/language/arithmetic_types#Complex_floating_types:
Each complex type has the same object representation and alignment requirements as an array of two elements of the corresponding real type (
float
forfloat complex
,double
fordouble complex
,long double
forlong double complex
). The first element of the array holds the real part, and the second element of the array holds the imaginary component.
所以,这样写是完全有效的:
complex double a;
{
complex_num a_ = dostuff(...);
memcpy(&a, &a_, sizeof(a));
}
自己写一个转换函数:
complex double MyCast(complex_num x) { return CMPLX(x.dat[0], x.dat[1]); }
CMPLX
是一个标准的宏,定义在<complex.h>
中。带有 clang-1001.0.46.4 和 GCC 9.1 的 Apple LLVM 10.0.1 将 CMPLX
的这种使用优化为无操作,至少在我测试的一种情况下是这样。