【问题标题】:How to efficiently work with complex numbers in C language?如何在 C 语言中有效地处理复数?
【发布时间】:2021-02-08 16:44:49
【问题描述】:

如何在 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 次复制(两个参数和一个返回)。 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 是如何实际传入函数并从函数返回的?是否像第一个带有结构的变体一样按值复制?

我应该使用哪种变体?

【问题讨论】:

  • 既然所有符合标准的 C 实现中已经有一个,为什么还要创建自己的实现?
  • 选项4)升级到C++
  • 选项 4) 通过传递 double complex * 组合选项 2 和 3。
  • Andrew Henle,我只是想了解 C99 标准数据类型“双复数”是如何实现的。

标签: c c99 complex-numbers


【解决方案1】:

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

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.

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

【讨论】:

  • C 标准根本没有规定复数的表示。
  • 如果“双复数”是两个实数的向量,这是否意味着它是一个由两个双精度数组成的数组?但据我所知,数组是通过指针而不是值传递给函数的。并且不能按值从函数返回数组。
  • @Kostiantyn_Hermash 它不是两个双精度数的数组,即使内存布局看起来像两个双精度数的数组。 struct complex_double 的内存布局也看起来像两个双精度数组......
  • @IanAbbott,这是完全错误的。我为此添加了 C 标准的引用。
  • @Kostiantyn_Hermash,/具有相同表示/和/being/浮点向量存在细微差别。请查看我的编辑。
猜你喜欢
  • 1970-01-01
  • 2015-01-19
  • 2014-11-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
相关资源
最近更新 更多