Python中复数的格式

时间:2012-11-14 21:38:29

标签: python complex-numbers

我想知道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

我在这里错过了什么吗?

4 个答案:

答案 0 :(得分:15)

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

这是关于虚部,而不是真实部分,但很容易想象实际部分的符号会产生类似差异的情况。

答案 1 :(得分: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 :(得分:2)

  • 0j是一个imaginary literal,它确实表示一个复数而不是一个整数或浮点数。

  • +-0(“有符号零”)是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 - > { {1}})。然后将(-0.0,0.0).real 添加添加到.imag 1j对应的(+0.0,1.0)。结果是(+0.0,1.0):^)。要直接构建复合体,请使用complex(-0.0,1)

答案 3 :(得分:1)

就第一个问题而言:如果它只是打印0,那么它在数学上是正确的,但你不会知道你正在处理complex对象与{{1} }。只要您没有指定int,您将始终获得J组件。

我不确定为什么你会得到.real;它在技术上不是错误的-0,但它在语法上是奇怪的。

就其他问题而言,奇怪的是它不一致,但技术上没有一个是正确的,只是实现的工件。