@@ -10,6 +10,7 @@ runnableExamples:
1010 # just as Python's
1111 assert not (type (complex (1 , 2 ).real) is int )
1212
13+ import std/ strformat
1314import std/ complex as ncomplex except im, complex, pow
1415export ncomplex.`/` # XXX: NIM-BUG: or
1516#[ lib/pure/complex.nim's `func inv*[T](z: Complex[T])` will:
@@ -42,14 +43,23 @@ template borrowAttr(expAs, attr){.dirty.} =
4243borrowAttr imag, im
4344borrowAttr real, re
4445
46+ func cut2str (result: var string ) =
47+ let lm2 = result .len - 2
48+ if result [lm2+ 1 ] == '0' and result [lm2] == '.' :
49+ result .setLen lm2
4550func cut2str [T: SomeFloat ](x: T): string =
4651 # Nim's Complex's elements can only be of float
4752 result = floatdollar.`$` x
4853 # removesuffix('.0')
4954 # We know $<float> will be at least 3 chars (e.g. "0.0", "inf")
50- let lm2 = result .len - 2
51- if result [lm2+ 1 ] == '0' and result [lm2] == '.' :
52- result .setLen lm2
55+ result .cut2str
56+
57+ template requirePlus (x: float ): bool =
58+ # act as `PyOS_double_to_string` with flag of `Py_DTSF_SIGN`
59+ x >= 0 or x.isNaN
60+ # NOTE: CPython's implementation does not care the sign of NaN here,
61+ # unconsistent with cases in other places
62+ # (CPython is used to caring a lot the sign of NaN)
5363
5464func repr * (z: PyTComplex ): string =
5565 # # Returns `bj/(a+bj)`/`(a-bj)` for `complex(a, b)`
@@ -70,12 +80,6 @@ func repr*(z: PyTComplex): string =
7080 return
7181 result .add '('
7282 result .add real.cut2str
73- template requirePlus (x: float ): bool =
74- # act as `PyOS_double_to_string` with flag of `Py_DTSF_SIGN`
75- x >= 0 or x.isNaN
76- # NOTE: CPython's implementation does not care the sign of NaN here,
77- # unconsistent with cases in other places
78- # (CPython is used to caring a lot the sign of NaN)
7983 if requirePlus imag:
8084 result .add '+'
8185 # if negative, `-` will be prefix-ed by `$`
@@ -84,6 +88,28 @@ func repr*(z: PyTComplex): string =
8488
8589func `$` * (z: PyTComplex ): string = repr z
8690
91+ proc formatValue * (res: var string , z: PyTComplex , spec: string ) =
92+ # # format complex with given spec, e.g. `format(complex(1, 2), ".2f")` -> "1.00+2.00j"
93+ # #
94+ # # Note that Python's `format` does not support `e`/`E` for complex, but Nim's does.
95+ # # So we support it as well.
96+ template addImag =
97+ res.formatValue z.imag, spec
98+ res.cut2str
99+ res.add 'j'
100+
101+ if z.real == 0.0 and copySign (1.0 , z.real) == 1.0 : # +0.0
102+ addImag
103+ return
104+
105+ res.add '('
106+ res.formatValue z.real, spec
107+ res.cut2str
108+ if requirePlus z.imag:
109+ res.add '+'
110+ addImag
111+ res.add ')'
112+
87113template toPyComplex [T](z: ncomplex.Complex [T]): PyTComplex [T] =
88114 # # Convert Nim's Complex in std/complex to PyTComplex
89115 bind PyTComplex
0 commit comments