如何在 C 语言中有效地处理复数?
How to efficiently work with complex numbers in C language?
如何在 C 语言中高效地处理复数?
我们有 3 个选项:
- 使用结构并将它们按值传递给函数:
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个字节,这可能是低效的。
- 将指针传递给结构:
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 字节。也许这样效率更高。
- 使用 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.
虽然它们的字节模式与浮点值的二元素向量相同,但它们与任何其他数字一样被视为算术类型。
如何在 C 语言中高效地处理复数?
我们有 3 个选项:
- 使用结构并将它们按值传递给函数:
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个字节,这可能是低效的。
- 将指针传递给结构:
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 字节。也许这样效率更高。
- 使用 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.
虽然它们的字节模式与浮点值的二元素向量相同,但它们与任何其他数字一样被视为算术类型。