2012-11-14 23 views
17

我很想知道Python(3.3.0)打印複數的方式。我正在尋找解釋,而不是改變印刷品的方式。Python中複數的格式

例子:

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

上午我在這裏錯過了什麼?

+0

關於'0j'部分,它是在Python常見的做法是'的eval(再版(X))== x' –

回答

14

它打印0j表示它仍然是complex值。您也可以以這種方式鍵入回:

>>> 0j 
0j 

剩下的就是可能的IEEE 754 floating point representation的魔力,這使得0和-0,所謂signed zero區分的結果。基本上,只有一點表明數字是正數還是負數,而不管數字是否爲零。這就解釋了爲什麼1j * -1給出了一個負實零部分:零正值乘以-1。

-0是標準所要求的等於+0,這就解釋了爲什麼(1j * -1).real == 0.0仍然成立。

了Python仍然決定打印-0究其原因,是在複雜的世界,這些使分支裁減差異,例如在the phase function

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

這是關於虛部,不真實的部分,但很容易想象真實部分的符號會產生類似差異的情況。

+2

我只想補充這個答案,所描述的所有情況下都是有效和Python作品如預期。您可以找到所有與IEEE 754相關的特殊測試用例:'Lib/tests/test_complex.py','test_negative_zero_repr_str' –

+1

剛剛測試過,看起來您對'-0'正確:>>> 0j.real .hex()' ''0x0.0p + 0'' '>>>(0j * -1).real.hex()' ''-0x0.0p + 0'' –

+0

我確認' - 0'部分:'print(0.0 * -1)'打印「'-0.0'」。而且由於Python中的'complex'類型是一對_float_數字,所以指定小數部分與否都無關緊要。 –

1

就第一個問題而言:如果它只是打印0這在數學上是正確的,但是你不知道你是在處理一個complex對象與一個int。只要你沒有指定.real你總會得到一個J組件。

我不確定爲什麼你會得到-0;它在技術上不是不正確的(-1 * 0 = 0),但它在語法上很古怪。

至於其餘的情況,奇怪的是它不一致,但是沒有一個在技術上是正確的,只是實現的一個人爲因素。

3

答案在於Python源代碼本身。

我會和你的一個例子一起工作。讓

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

當你做a*b你打電話this function

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,你'negative zero,因爲that's not +0,你會得到parens和打印它的真實部分。

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. */ 
... 

我猜(但我不知道肯定),與基本的複雜功能計算時的理由來自於符號的重要性(有這個維基百科文章中籤署零引用)。

2
  • 0jimaginary literal這的確表示複數而不是一個整數或浮點之一。

  • +-0(「signed zero」)是Python與IEEE 754 floating point representation一致的結果,因爲在Python中爲complex is by definition a pair of floating point numbers。由於後者,也不需要爲complex打印或指定零分數部分。

  • -0部分是爲了準確地表示內容as repr()'s documentation demands印刷repr()被隱含稱爲每當操作的結果被輸出到控制檯)。

  • 關於問題爲什麼(-0+1j) = 1j但是(1j*-1) = (-0+1j) 注意(-0+0j)(-0.0+0j)不是單複數,但表達 - 一個int/float添加到complex。要計算結果,首先將第一個數字轉換爲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)

+0

感謝關於str/repr的解釋。但是這裏「print(0j * -1)」仍然返回「(-0 + 0j)」,所以它的行爲相同。此外,* if * python嚴格遵循IEEE標準的repr(),爲什麼「print(-0 + 0j)」返回「0j」? – cxxl

+0

2cxxl:'(-0 + 0j)'不是一個複數,而是一個表達式 - 一個添加到複數的整數。當計算結果時,「-0」被轉換爲一個複合體並添加到它的「.real」,即「0」。結果是'+ 0':^) –

+0

因爲我在這種情況下對'str()'的假設被證明是錯誤的,所以我抹去了它。 –