使用C ++中的std :: complex <t>创建复杂的无穷大</t>

时间:2012-05-14 16:02:16

标签: c++ nan infinity complex-numbers numeric-limits

我正在尝试创建一个等于Inf + Inf * j的复数无穷大,其中j是复数变量。当我这样做时:

#include <complex>
#include <limits>
using std;

...

complex<double> attempt1 =
   complex<double>( numeric_limits<double>::infinity(),
                    numeric_limits<double>::infinity() );

返回复数(NaN + Inf * j)。

但是

complex<double> attempt2 =
   complex<double>( numeric_limits<double>::infinity() );

返回复数(Inf + 0 * j)。

另外:

complex<double> attempt_at_imag_inf =
   complex<double>(any_value_here, numeric_limits<double>::infinity());

返回复数(NaN + Inf * j)。

有人知道这里发生了什么吗?任何时候我试图为想象的部分设置infinty,那么NaN写在真实的部分。

以上仅适用于支持NaN和Infinity的类型。我正在使用g ++ v4.6.1。我查看了numeric_limits标题,并没有迹象表明上述情况应该发生。

为了将上述内容置于上下文中,我实际上是在对complex的numeric_limits的部分特化中进行上述操作。非常感谢您考虑这个问题。

原始发布的修订

我正在提供一个完整但简短的程序来说明问题。我还提供了一些关于如何编译程序以生成结果的更多合格信息。

#include <iostream>
#include <complex>
#include <limits>

using namespace std;

int main(int argc, char* argv[])
{

   complex<double> my_complex_inf =
      complex<double>(numeric_limits<double>::infinity(),
                      numeric_limits<double>::infinity());

   cout << "my_complex_inf = " << my_complex_inf << endl;

   complex<double> attempt2 =
      complex<double>( numeric_limits<double>::infinity() );

   cout << "attempt2 = " << attempt2 << endl;

   double any_value_here = 0;

   complex<double> attempt_at_imag_inf =
      complex<double>(0, numeric_limits<double>::infinity());

   cout << "attempt_at_imag_inf = " << attempt_at_imag_inf << endl;

   return 0;

}

使用-std = c ++ 0x在Ubuntu上的g ++版本4.6.1中编译以上结果:

my_complex_inf = (nan,inf)
attempt2 = (inf,0)
attempt_at_imag_inf = (nan,inf)

如果没有-std = c ++ 0x选项,结果为:

my_complex_inf = (inf,inf)
attempt2 = (inf,0)
attempt_at_imag_inf = (0,inf)

所以问题是为什么GNU g ++ V4.6.1在指定C ++ 0x时会给出答案?

修订2原始邮寄

我刚刚在Octave(类似MATLAB的数字包)中尝试了以下内容:

a = inf + j * inf

答案是:

a = NaN + Infi

这正是我在C ++ 11代码(C ++ 0x)中看到的。我不知道Octave是用什么编译的(它是我认为的C ++和FORTRAN的组合)但如果该包返回我得到的结果,那么我认为这是众所周知的行为。

但是,我已经查看了C ++ 11草案标准,并且找不到任何关于此行为的提及。

修订3原始邮寄

添加以下行

my_complex_inf.real(my_complex_inf.imag());

在构造my_complex_inf之后,在为C ++ 11编译时返回“正确”答案(inf,inf)。不幸的是,现在这是一个两步过程,我无法在constexpr函数中创建这种复杂的无穷大。

3 个答案:

答案 0 :(得分:4)

转换为复合体的标量Inf为inf + 0 j。这是正确的。复平面中的标量Inf偏移意味着旋转,并且不可计算,因此Nan是正确的。又是什么问题?

“有龙。”

答案 1 :(得分:4)

你正在遇到C ++ 11(和C11)指定复数并混淆的方式。

基本上,在规范规定的模型中,只有一个无穷大(由(inf,0)表示),并且尝试将“无穷大”放入复数的虚部中会导致Nan,因为它会使在那个模型中毫无意义。

答案 2 :(得分:0)

在主线(gcc-4.8)中,我得到-std = c ++ 0x预期的(没有-std)答案:

my_complex_inf = (inf,inf)
attempt2 = (inf,0)
attempt_at_imag_inf = (0,inf)

gcc-4.6.3 with -std-c ++ 11给出了意想不到的答案:

my_complex_inf = (-nan,inf)
attempt2 = (inf,0)
attempt_at_imag_inf = (-nan,inf)

我认为构造函数应该根据相应的参数设置实数和虚数类型。应该没有nan