如何将无穷大值传递给函数并测试结果

时间:2017-02-08 15:11:31

标签: c c99 complex-numbers

我有这个功能:

#include <complex.h>
complex double f(complex double x, complex double y) {
  return x*y;
}

我想用x = inf + i infy = i inf来调用它,看看结果是什么。特别是我想测试结果是无穷大值(应该是)还是NaN + iNaN。这样做的原因是测试不同的C编译器。

  

你在C中怎么做?

4 个答案:

答案 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)