代码之家  ›  专栏  ›  技术社区  ›  Siddharth

复制Python的复数到字符串转换

  •  0
  • Siddharth  · 技术社区  · 6 年前
    import operator
    >>> operator.truediv(-5.6, complex(-1, 0)) #eg1
    (5.6-0j)
    >>> operator.truediv(-5.6, complex(0, -1)) #eg2
    (-0-5.6j)
    >>> operator.truediv(-5.6, complex(0, 1)) #eg3
    5.6j
    >>> operator.truediv(-5.6, complex(1, 0)) #eg4
    (-5.6+0j)
    >>> operator.truediv(5.6, complex(0,-1)) #eg 5
    (-0+5.6j)
    

    有没有办法知道将复数转换为Python交互式解释器中显示的字符串表示的确切规则?像一些人一样,

    1. 在eg1中打印 0j 但在eg3中,情况并非如此。

    2. 有时它会打印 0 , -0 如eg1和eg4

    3. eg2和eg5。

    我知道这没什么区别,但我想实现与Python完全相同的功能。我的意思是输出应该完全相同。

    任何帮助都将不胜感激。 而且这不是家庭作业问题,也谢谢你的阅读。

    2 回复  |  直到 6 年前
        1
  •  2
  •   Duncan    6 年前

    Python将始终显示复数的虚部,因为否则您无法从输出中区分它确实是复杂的。这类似于包括 .0 在浮点数上,即使它是一个整数。

    实际零件在不完全为+0时显示。在您给出的示例中,显示真实零件是因为它是负零。请注意,在浮点中,负零和正零具有不同的表示形式,即使它们比较相等:

    >>> float.fromhex('-0x0.0')
    -0.0
    >>> float.fromhex('0x0.0')
    0.0
    >>> float.fromhex('-0x0.0') == 0.0
    True
    

    这对于模拟Python的输出可能没有多大帮助,因为您可能无法轻松预测Python何时会得到负0的结果。例如:

    >>> neg0 = float.fromhex('-0x0.0')
    >>> neg0
    -0.0
    >>> neg0+0j
    0j
    

    加法将实部归一化为+0

    >>> neg0*1j
    (-0+0j)
    >>> 0.0*(-1j)
    -0j
    

    与正虚数相乘会保留实部的负号,但与负虚数相乘不会使实部为负。

    但所有这些都只是实现细节,因此不同的Python实现可能会有所不同。

    浮点有两个独立的正负零表示,这是IEEE 754浮点实现的一个细节。看见 https://en.wikipedia.org/wiki/Signed_zero

    检测是否输出真实部分的源代码部分包括:

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

    第一部分适用于两种形式的零。只有当真实部分不是负数时,第二部分才是真的( copysign(x,y) 给出的值为 x 带有 y 所以 copysign(1.0, negativezero) 可能是 -1 .

        2
  •  2
  •   Cong Ma    6 年前

    如果要实现另一个程序来精确复制CPython解释器的当前行为,可以研究复数表示的源代码: static PyObject * complex_repr (PyComplexObject *v) . 此函数负责将复数默认转换为字符串。

    一些血淋淋的细节可以在函数中找到 PyAPI_FUNC(char *) PyOS_double_to_string (double val, char format_code, int precision, int flags, int *type) .

    我不认为浮点数的精确交互式输出是官方Python语言规范的一部分,所以这里的源代码可能是最好的指南。


    编辑:如果你不想重新发明轮子,那么可能是时候研究一下了 embedding Python in another application .