2012-11-14 7 views
17

파이썬 (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 

오전 나는 여기서 뭔가를 놓친거야?

+0

, 그것은 파이썬에서 일반적인 관행입니다 평가 (를 repr (x)를) == x' –

답변

14

여전히 complex 값임을 나타 내기 위해 0j을 인쇄합니다. 또한 그 방법으로 그것을 다시 입력 할 수 있습니다

>>> 0j 
0j 

나머지는 아마도 signed zero 소위 0 -0, 구별하게 IEEE 754 floating point representation의 마법의 결과이다. 기본적으로 숫자가 0인지 여부에 관계없이 숫자가 양수인지 음수인지 여부를 나타내는 단일 비트가 있습니다. 이것은 1j * -1이 음의 제로 실수 부분을주는 이유를 설명합니다. 양수 0에 -1이 곱해집니다.

-0은 표준에 의해 +0과 같아야하는데, 이는 (1j * -1).real == 0.0이 아직 보유하고있는 이유를 설명합니다.

파이썬은 여전히 ​​-0를 인쇄하기로 결정하는 이유, 복잡한 세계에서 이러한 the phase function에서 예를 들어, 지점 인하 차이를 만들 것입니다 : 이것은 허수 부분에 관한 것입니다

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

하지 실수 부분의 부호가 비슷한 차이를 만드는 상황을 상상하기 쉽습니다.

+2

난 그냥 모든 기술의 경우가 유효한지,이 답변에 추가 할 파이썬 작품'그 예상대로 IEEE 754와 관련된 모든 표현으로 특별한 테스트 케이스를 찾을 수 있습니다 :'Lib/tests/test_complex.py','test_negative_zero_repr_str' –

+1

그냥 테스트했는데'-0'에 대해 정확하다고 나타납니다 :'>>> 0j.real 0x00.0p + 0 " >>> (0j * -1) .real.hex()' '-0x0.0p + 0 ' –

+0

'- 0'부분 :'print (0.0 * -1)'은 "-0.0'"을 출력합니다. 그리고 파이썬에서'complex' 타입은 _float_ 숫자의 쌍이기 때문에 소수 부분을 지정했는지 여부는 중요하지 않습니다. –

1

첫 번째 질문과 관련하여 : 방금 0을 인쇄하면 수학적으로 올바르지 만 complex 개체를 다루는 것을 알지 못하지만 int 인 것입니다. .real을 지정하지 않으면 항상 J 구성 요소가 제공됩니다.

나는 왜 당신이 이제까지 -0을 얻을 것입니다 확실하지 않다; 그것은 기술적으로 올바르지 않습니다. (-1 * 0 = 0)하지만 문법적으로 이상합니다.

나머지 부분까지는 일관성이 없다는 것이 이상하지만 기술적으로는 정확하지 않으며 구현의 인공물입니다.

3

대답은 파이썬 소스 코드 자체에 있습니다.

예제 중 하나를 사용하여 작업하겠습니다. 당신을

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

을 그리고 당신이 경우에 파이썬 인터프리터, 당신은 IEEE754에서

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

을 얻을 것이라는 점 : 당신이 a*b을 수행 할 때 당신이 this function를 호출하고

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

하자 negative zero을 받고, that's not +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. */ 
... 

내가 생각 (하지만 난 확실히 모르는) 초등학교 복잡한 기능을 계산할 때 이론적 근거는 그 기호의 중요성에서 온다 (서명 제로에 위키 피 디아 기사에서이에 대한 참조있다).

2
  • 0j 실제로 복소수 아닌 정수 또는 부동 소수점을 나타내는 imaginary literal이다.

  • +-0 ("부호가없는 0")은 IEEE 754 floating point representation에 대한 파이썬의 적합성 결과로 complex is by definition a pair of floating point numbers입니다. 후자의 경우 complex도 제로 부분을 인쇄하거나 지정하지 않아도됩니다.

  • -0 부분 (작업의 결과가 콘솔에 출력 될 때마다 repr() 암시라고 함)를 정확하게 as repr()'s documentation demands 내용을 표현하기 위해 인쇄이다.

  • 질문에 대해서는 (-0+1j) = 1j 그러나 (1j*-1) = (-0+1j)입니다. int/floatcomplex에 추가 - (-0+0j) 또는 (-0.0+0j) 단일 복잡한 숫자 만 표현 아니라는 것을 참고. 결과를 계산하려면 먼저 숫자가 complex (-0 ->(0.0,0.0))으로 변환됩니다 (정수에는 부호가없는 0이 있으므로 -0.0 ->(-0.0,0.0)). 그 후, .real.imag1j의 대응하는 것, 즉 (+0.0,1.0)에 대해 으로 더한 것입니다. 결과는 (+0.0,1.0) : ^)입니다. 복합체를 직접 생성하려면 complex(-0.0,1)을 사용하십시오. 은`0j` 부분에 대해서는

+0

str/repr에 대한 설명 주셔서 감사합니다. 하지만 여기서 "print (0j * -1)"는 여전히 "(-0 + 0j)"를 반환하기 때문에 동일하게 동작합니다. 게다가 * if * python이 repr()을 사용하여 IEEE 표준을 엄격하게 준수한다면 "print (-0 + 0j)"가 "0j"를 반환하는 이유는 무엇입니까? – cxxl

+0

2cxxl :'(-0 + 0j)'는 하나의 복소수가 아니라 표현식 - 복소수에 더해진 정수입니다. 결과가 계산 될 때,'-0'은 복소수로 변환되어'.real'에 추가됩니다. 그것은'0'입니다. 결과는'+ 0' : ^) –

+0

이 경우'str()'에 대한 나의 가정이 거짓으로 판명 되었기 때문에 나는 그것을 지웠다. –