14

我正在尝试创建一个等于 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)。

有人知道这里发生了什么吗?每当我尝试将虚部设为无穷大时,就会在实部上写入 NaN。

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

为了将上述内容置于上下文中,我实际上是在对复杂的 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;

}

在 Ubuntu 上使用 -std=c++0x 在 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-like numerics package) 中尝试了以下内容:

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());

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

4

3 回答 3

4

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

“有龙。”

于 2012-05-16T20:31:14.117 回答
4

您遇到了 C++11(和 C11)指定复数并感到困惑的方式。

基本上,在规范规定的模型中,只有一个无穷大(由 (inf,0) 表示),并试图将“无穷大”放入 Nan 中复数结果的虚部,因为在那个模型。

于 2012-05-16T23:18:17.613 回答
0

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

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

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

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

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

于 2012-05-17T02:29:32.430 回答