我有这个功能:
#include <complex.h>
complex double f(complex double x, complex double y) {
return x*y;
}
我想用x = inf + i inf
和y = i inf
来调用它,看看结果是什么。特别是我想测试结果是无穷大值(应该是)还是NaN + iNaN
。这样做的原因是测试不同的C编译器。
你在C中怎么做?
答案 0 :(得分:2)
我并非100%确定这是正确的,因为我从未使用过C中的复杂数字,但我已尝试过这段代码:
#include <stdio.h>
#include <math.h>
#include <complex.h>
double complex f(double complex x, double complex y) {
return x*y;
}
int main(void)
{
double complex z1 = INFINITY + INFINITY * I;
double complex z2 = INFINITY + INFINITY * I;
complex double result = f(z1, z2);
printf("%f + i%f\n", creal(result), cimag(result));
}
我使用了clang 3.8(C 11)和GCC 6.1(C 11),结果是:
-inf + i-nan
基于http://en.cppreference.com/w/c/numeric/math/INFINITY。
显然,并不总是支持宏INFINITY
并因此定义它。请查看上面的链接以获取更多信息。
答案 1 :(得分:2)
我也会添加中间检查:
#include <stdio.h>
#include <stdlib.h>
#include <complex.h>
#include <math.h>
complex double f(complex double x, complex double y) {
return x*y;
}
int main(void){
complex double x = INFINITY + INFINITY * I;
complex double y = 0.0 + INFINITY * I;
complex double ret;
printf("x = %g + %g*I\n", creal(x), cimag(x));
printf("y = %g + %g*I\n", creal(y), cimag(y));
ret = f(x,y);
printf("f = %g + %g*I\n", creal(ret), cimag(ret));
exit(EXIT_SUCCESS);
}
为什么?
gcc-4.9.real的结果(Ubuntu 4.9.4-2ubuntu1~14.04.1)4.9.4
x = nan + inf*I
y = nan + inf*I
f = -inf + -nan*I
Ubuntu clang版本3.4-1ubuntu3(标签/ RELEASE_34 / final)的结果(基于LLVM 3.4)
x = nan + inf*I
y = nan + inf*I
f = nan + nan*I
从一开始就完全彻底失败。
答案 2 :(得分:1)
您可以使用与I
宏(也有_Complex_I
别名的乘法来指定基本上复杂的文字。创建这样一个值的一个小例子如下所示:
#include <math.h>
#include <complex.h>
int main()
{
complex c = INFINITY * I + INFINITY;
}
答案 3 :(得分:1)
编写的函数很好,问题在于创建和解释具有特殊值的复数的方式。
如果你只是写
double complex z1 = I * INFINITY;
double complex z2 = INFINITY + I * INFINITY;
你可能会发现今天大多数流行的编译器不支持C99&#39; imaginary numbers,这个表达式实际上将(0,1)乘以(inf,0)然后加上(inf,0 )结果。
使用gcc,我得到z1 =(nan,inf),z2 =(nan,inf),f(z1,z2)=(-inf,-nan)
用clang,我得到z1 =(nan,inf),z2 =(nan,inf),f(z1,z2)=(-inf,-nan)
使用icc,我得到z1 =( - nan,inf),z2 =( - nan,inf),f(z1,z2)=( - nan,-nan)
将I定义为我可以访问的纯虚数的唯一编译器是Oracle Studio的C编译器
使用oracle studio,我得到z1 =(0,inf),z2 =(inf,inf),f(z1,z2)=( - inf,inf)
现在这实际上不应该是一个问题,因为在C中,只有一个复合无穷大,并且其中一个组件为无穷大的每个复数都被认为是无穷大,即使另一个组件是NaN。所有内置算术都是supposed to honor that:所以在上面的列表中,只有英特尔似乎有一个错误,其中两个复杂无穷大的乘法给出了复杂的纳米。
对于惰性编译器,C11有一个节省日期的宏:CMPLX
double complex z1 = CMPLX(0, INFINITY);
double complex z2 = CMPLX(INFINITY, INFINITY);
现在,
使用gcc,我得到z1 =(0,inf),z2 =(inf,inf),f(z1,z2)=( - inf,inf)