如何在 C 语言中有效地处理复数?

How to efficiently work with complex numbers in C language?

如何在 C 语言中高效地处理复数?

我们有 3 个选项:

  1. 使用结构并将它们按值传递给函数:
struct complex_double
{
   double data[2];
}

typedef struct complex_double ComplexDouble;

ComplexDouble complex_double_add(ComplexDouble z_1, ComplexDouble z_2)
{
   ComplexDouble result;

   result.data[0] = z_1.data[0] + z_2.data[0];
   result.data[1] = z_1.data[1] + z_2.data[1];

   return result;
}

但是通过这种方式,我们有 3 次结构值的复制(两个参数和一个 return)。 ComplexDouble的大小是16个字节,所以我们需要复制3 * 16个字节= 48个字节,这可能是低效的。

  1. 将指针传递给结构:
struct complex_double
{
   double data[2];
}

typedef struct complex_double ComplexDouble;

ComplexDouble * complex_double_initialize(double x, double y)
{
   ComplexDouble *z;
   
   z = (ComplexDouble *)malloc( sizeof(ComplexDouble) );

   if(z == NULL)
   {
     fprintf(stderr, "complex_double_initialize: Error! Failed to allocate memory for ComplexDouble\n");
     exit(EXIT_FAILURE);
   }

   z->data[0] = x;
   z->data[1] = y;

   return z;
}

void complex_double_add(ComplexDouble *result, ComplexDouble *z_1, ComplexDouble *z_2)
{
   result->data[0] = z_1->data[0] + z_2->data[0];
   result->data[1] = z_1->data[1] + z_2->data[1];
}

在此变体中,我们将 3 个指针传递给结构,即 3 * 8 字节 = 24 字节。也许这样效率更高。

  1. 使用 C99 标准库中的复杂类型:
double complex z_1, z_2, z_3;

z_3 = z_1 + z_2;

double complex double_complex_add(double complex z_1, double complex z_2)
{
   return (z_1 + z_2);
}

但是对于 C99 复杂类型,我有一些不明白的地方。 double complex 实际上是如何传递到函数中并 return 从函数中传递出来的?它是否像第一个带有结构的变体一样按值复制?

我应该使用哪个变体?

使用它的标准版本。它现在已集成到编译器中,是您可以获得的最好的。

How is double complex actually passed into function and returned from function?

正如您的函数规范所示,它们可以按值访问,对于任何其他函数参数也是如此,除非它们具有数组类型。

复数保证与两个实数的向量具有相同的表示(=内存布局),但它们是正确的类型:

Each complex type has the same representation and alignment requirements as an array
type containing exactly two elements of the corresponding real type; the first element is
equal to the real part, and the second element to the imaginary part, of the complex
number.

虽然它们的字节模式与浮点值的二元素向量相同,但它们与任何其他数字一样被视为算术类型。