Format Of Complex Number In Python
Solution 1:
It prints 0j
to indicate that it's still a complex
value. You can also type it back in that way:
>>> 0j
0j
The rest is probably the result of the magic of IEEE 754 floating point representation, which makes a distinction between 0 and -0, the so-called signed zero. Basically, there's a single bit that says whether the number is positive or negative, regardless of whether the number happens to be zero. This explains why 1j * -1
gives something with a negative zero real part: the positive zero got multiplied by -1.
-0 is required by the standard to compare equal to +0, which explains why (1j * -1).real == 0.0
still holds.
The reason that Python still decides to print the -0, is that in the complex world these make a difference for branch cuts, for instance in the phase
function:
>>> phase(complex(-1.0, 0.0))
3.141592653589793
>>> phase(complex(-1.0, -0.0))
-3.141592653589793
This is about the imaginary part, not the real part, but it's easy to imagine situations where the sign of the real part would make a similar difference.
Solution 2:
The answer lies in the Python source code itself.
I'll work with one of your examples. Let
a = complex(0,1)
b = complex(-1, 0)
When you doa*b
you're calling this function:
real_part = a.real*b.real - a.imag*b.imag
imag_part = a.real*b.imag + a.imag*b.real
And if you do that in the python interpreter, you'll get
>>> real_part
-0.0
>>> imag_part
-1.0
From IEEE754, you're getting a negative zero, and since that's not +0, you get the parens and the real part when printing it.
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. */
...
I guess (but I don't know for sure) that the rationale comes from the importance of that sign when calculating with elementary complex functions (there's a reference for this in the wikipedia article on signed zero).
Solution 3:
0j
is an imaginary literal which indeed indicates a complex number rather than an integer or floating-point one.The
+-0
("signed zero") is a result of Python's conformance to IEEE 754 floating point representation since in Python,complex
is by definition a pair of floating point numbers. Due to the latter, there's no need to print or specify zero fraction parts for acomplex
too.The
-0
part is printed in order to accurately represent the contents asrepr()
's documentation demands (repr()
is implicitly called whenever an operation's result is output to the console).Regarding the question why
(-0+1j) = 1j
but(1j*-1) = (-0+1j)
. Note that(-0+0j)
or(-0.0+0j)
aren't single complex numbers but expressions - anint
/float
added to acomplex
. To compute the result, first the first number is converted to acomplex
(-0
->(0.0,0.0)
since integers don't have signed zeros,-0.0
->(-0.0,0.0)
). Then its.real
and.imag
are added to the corresponding ones of1j
which are(+0.0,1.0)
. The result is(+0.0,1.0)
:^) . To construct a complex directly, usecomplex(-0.0,1)
.
Solution 4:
As far as the first question is concerned: if it just printed 0
it would be mathematically correct, but you wouldn't know you were dealing with a complex
object vs an int
. As long as you don't specify .real
you will always get a J component.
I'm not sure why you would ever get -0
; it's not technically incorrect (-1 * 0 = 0)
but it's syntactically odd.
As far as the rest goes, it's strange that it isn't consistent, however none are technically correct, just an artifact of the implementation.
Post a Comment for "Format Of Complex Number In Python"