我正在尝试创建一个等于 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 函数中创建这种复杂的无穷大。