web-dev-qa-db-ja.com

Pythonの複素数の形式

Python(3.3.0)が複素数を出力する方法について疑問に思っています。印刷を変更する方法ではなく、説明を探しています。

例:

>>> complex(1,1)-complex(1,1)
0j

なぜ「0」を出力しないのですか?私の推測では、複合型の出力を維持することです。

次の例:

>>> complex(0,1)*-1
(-0-1j)

さて、単純な「-1j」または「(-1j)」でした。そして、なぜ「-0」?? +0と同じではないですか?丸めの問題ではないようです。

>>> (complex(0,1)*-1).real == 0.0
True

そして、虚数部が正になると、-0は消えます。

>>> complex(0,1)
1j
>>> complex(0,1)*-1
(-0-1j)
>>> complex(0,1)*-1*-1
1j

さらに別の例:

>>> complex(0,1)*complex(0,1)*-1
(1-0j)
>>> complex(0,1)*complex(0,1)*-1*-1
(-1+0j)
>>> (complex(0,1)*complex(0,1)*-1).imag
-0.0

ここで何かが足りませんか?

19
cxxl

0jを出力して、それがまだcomplex値であることを示します。次のように入力し直すこともできます。

>>> 0j
0j

残りはおそらく IEEE 754浮動小数点表現 の魔法の結果であり、0と-0を区別します。いわゆる 符号付きゼロ です。基本的に、数値がゼロであるかどうかに関係なく、数値が正か負かを示す1つのビットがあります。これは、1j * -1が負のゼロの実数部を持つものを与える理由を説明しています。正のゼロは-1で乗算されます。

+0と同等に比較するには、標準で-0が必要です。これは、(1j * -1).real == 0.0が引き続き保持される理由を説明しています。

Pythonがまだ-0を出力することを決定する理由は、複雑な世界では、これらが分岐カットに違いをもたらすためです。たとえば、 phase関数

>>> phase(complex(-1.0, 0.0))
3.141592653589793
>>> phase(complex(-1.0, -0.0))
-3.141592653589793

これは実数部ではなく虚数部に関するものですが、実数部の符号が同様の違いをもたらす状況を想像するのは簡単です。

15
Thomas

答えはPythonソースコード自体にあります。

私はあなたの例の1つを扱います。しましょう

a = complex(0,1)
b = complex(-1, 0)

あなたがするときa*bあなたが呼んでいる この関数

real_part = a.real*b.real - a.imag*b.imag
imag_part = a.real*b.imag + a.imag*b.real

そして、pythonインタープリターでそれを行うと、次のようになります

>>> real_part
-0.0
>>> imag_part
-1.0

IEEE754から、 負のゼロ を取得します。 + 0ではない なので、印刷時に親と実数部を取得します。

if (v->cval.real == 0. && copysign(1.0, v->cval.real)==1.0) {
    /* Real part is +0: just output the imaginary part and do not
       include parens. */
...
else {
    /* Format imaginary part with sign, real part without. Include
       parens in the result. */
...

理論的根拠は、基本的な複素関数で計算するときのその符号の重要性に由来すると思います(これについては、ウィキペディアの符号付きゼロに関する記事に参照があります)。

3
jorgeca
  • _0j_は 虚数リテラル であり、整数や浮動小数点数ではなく、実際に複素数を示します。

  • _+-0_( "signed zero")は、Pythonが IEEE 754浮動小数点表現 に準拠している結果です。Pythonでは complexは定義上ペアであるため) 浮動小数点 。後者のため、complexの小数部を印刷または指定する必要もありません。

  • _-0_の部分は、内容を正確に表すために印刷されています repr()のドキュメントの要求に応じてrepr()は、操作の結果がコンソールに出力されるたびに暗黙的に呼び出されます)。

  • 質問についてなぜ_(-0+1j) = 1j_が_(1j*-1) = (-0+1j)_。_(-0+0j)_または_(-0.0+0j)_はそうではないことに注意してください単一の複素数ですが、-int/floatcomplexに追加されました。結果を計算するには、最初に最初の数値をcomplex(_-0_-> _(0.0,0.0)_に変換します。整数には符号付きゼロがないため、_-0.0_-> _(-0.0,0.0)_)。次に、その_.real_と_.imag_が_1j_の対応するもの(_(+0.0,1.0)_)に追加されます。結果は_(+0.0,1.0)_:^)です。複合体を直接作成するには、complex(-0.0,1)を使用します。

2
ivan_pozdeev

最初の質問に関する限り、0を出力しただけの場合、数学的には正しいでしょうが、complexオブジェクトとintを扱っているかどうかはわかりません。 。 .realを指定しない限り、常にJコンポーネントを取得します。

なぜあなたが-0を手に入れるのかわかりません。技術的には正しくありません(-1 * 0 = 0)ですが、構文的には奇妙です。

残りの部分に関しては、一貫性がないのは不思議ですが、技術的に正しいものはなく、実装の成果物にすぎません。

1
dbarnett