14

j が複雑な変数である Inf+Inf*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;

}

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

したがって、実際の問題は、C++0x が指定されている場合に GNU g++ V4.6.1 が回答を返すのはなぜですか?

元の投稿の改訂 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) が返されます。残念ながら、これは現在 2 段階のプロセスであり、constexpr 関数でこの種の複雑な無限を作成することはできません。

4

3 に答える 3

4

複素数に変換されたスカラーInfはinf+0jです。上記は正しいです。複素平面のスカラーInfオフセットは、回転を意味し、計算できないため、Nanは正しいです。再び問題は何ですか?

「ドラゴンがいる」

于 2012-05-16T20:31:14.117 に答える
4

C++11 (および C11) が複素数を指定する方法に遭遇し、混乱しています。

基本的に、仕様で義務付けられているモデルでは、無限大 ((inf,0) で表される) は 1 つだけであり、「無限大」を複素数の虚部に入れようとすると、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 に答える