| msg288177 - (view) | Author: Tom Krauss (Tom Krauss) | Date: 2017-02-20 00:49 |
Consider the following simple class that provides a "__complex__" method. class C(object): def __init__(self, x): self.x = x def __complex__(self): return self.x x=C(-0j) PYTHON 2.7.13 >>> x.x -0j >>> complex(x) 0j PYTHON 3.6 >>> x.x (-0-0j) >>> complex(x) (-0+0j) |
| msg288192 - (view) | Author: Mark Dickinson (mark.dickinson) *  | Date: 2017-02-20 11:13 |
Confirmed on my machine. The effect of the source is to do `complex(complex(x), 0.0)` in this case, which isn't correct. |
| msg288196 - (view) | Author: Mark Dickinson (mark.dickinson) *  | Date: 2017-02-20 11:41 |
Looking at the source, there's also an issue with complex subclasses here: >>> class C(complex): ... pass ... >>> complex(C(-0j)) (-0+0j) >>> complex(-0j) (-0-0j) |
| msg288205 - (view) | Author: Armin Rigo (arigo) *  | Date: 2017-02-20 14:04 |
CPython 2.7 and 3.5 have issues with the sign of zeroes even without any custom class: >>> -(0j) # this is -(0+0j) (-0-0j) >>> (-0-0j) # but this equals to the difference between 0 and 0+0j 0j >>> (-0.0-0j) # this is the difference between -0.0 and 0+0j (-0+0j) >>> -0j -0j # <- on CPython 2.7 (-0-0j) # <- on CPython 3.5 It's unclear if the signs of the two potential zeroes in a complex number have a meaning, but the C standard considers these cases for all functions in the complex number's header. |
| msg288207 - (view) | Author: Mark Dickinson (mark.dickinson) *  | Date: 2017-02-20 14:18 |
Armin: that's a separate issue, and is expected behaviour. >>> -(0j) # this is -(0+0j) (-0-0j) Yes: 0j is complex(0.0, 0.0); negating negates both the real and imaginary parts. >>> (-0-0j) # but this equals to the difference between 0 and 0+0j 0j This is an operation between an integer (note that the initial negation is a no-op) and a complex. Here the integer gets promoted to complex(0.0, 0.0), and we do complex(0.0, 0.0) - complex(0.0, 0.0), which gives complex(0.0, 0.0). >>> (-0.0-0j) # this is the difference between -0.0 and 0+0j (-0+0j) This is complex(-0.0, 0.0) - complex(0.0, 0.0). The real and imaginary parts are operated on separately, and in keeping with IEEE 754, the real part is evaluated as -0.0 - 0.0, which is -0.0. >>> -0j -0j # <- on CPython 2.7 (-0-0j) # <- on CPython 3.5 The Python 3 behaviour here is correct. The Python 2 behaviour is the result of an unfortunate AST optimization designed to ensure that -<sys.maxint+1> is an int rather than a long. None of the above is a new issue. |
| msg288208 - (view) | Author: Mark Dickinson (mark.dickinson) *  | Date: 2017-02-20 14:20 |
> It's unclear if the signs of the two potential zeroes in a complex number have a meaning Yes, very much so. The signs are important in determining which side of a branch cut to use in the various cmath functions. |
| msg288210 - (view) | Author: Armin Rigo (arigo) *  | Date: 2017-02-20 14:40 |
Maybe I should be more explicit: what seems strange to me is that some complex numbers have a repr that, when entered in the source, produces a different result. For example, if you want the result ``(-0-0j)`` you have to enter something different. However, I missed the fact that calling explicitly ``complex(a, b)`` with a and b being floats always gives exactly a+bj with the correct signs. So I retract my comments. |
| msg288211 - (view) | Author: STINNER Victor (vstinner) *  | Date: 2017-02-20 14:43 |
IMHO it would be less surprising if repr(complex) would return 'complex(..., ...)': it would be possible to copy/paste and get the result value. I was bitten multiple time by the zero sign with complex numbers... |
| msg288212 - (view) | Author: Mark Dickinson (mark.dickinson) *  | Date: 2017-02-20 14:47 |
Armin, Victor: please open other issues for these discussions; they're unrelated to the bug reported here. Also, see #27363, #17336, #22548, #25839. |
| msg288223 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) *  | Date: 2017-02-20 18:00 |
Proposed patch fixes constructing complex from complex. But in future versions perhaps it is worth to disallow passing complex argument to two-arguments complex constructor. |
| msg288224 - (view) | Author: Armin Rigo (arigo) *  | Date: 2017-02-20 18:07 |
4 lines before the new "ci.real = cr.imag;", we have "cr.imag = 0.0; /* Shut up compiler warning */". The comment is now wrong: we really need to set cr.imag to 0.0. |
| msg288229 - (view) | Author: Mark Dickinson (mark.dickinson) *  | Date: 2017-02-20 19:27 |
complex-constructor-from-complex2.patch looks good to me. What happens now? I presume we can no longer push to hg.python.org? So one of us needs to make a PR on GitHub and another review it? |
| msg288231 - (view) | Author: Serhiy Storchaka (serhiy.storchaka) *  | Date: 2017-02-20 19:54 |
I pushed changes to my fork but when try to create a pull request it contains unrelated changes. Seems I do something wrong. |
| msg288233 - (view) | Author: Mark Dickinson (mark.dickinson) *  | Date: 2017-02-20 20:10 |
Created https://github.com/python/cpython/pull/203, but I feel bad for having my name on the commits. :-( |
| msg288236 - (view) | Author: Mark Dickinson (mark.dickinson) *  | Date: 2017-02-20 20:28 |
New changeset 112ec38c15b388fe025ccb85369a584d218b1160 by GitHub in branch 'master': bpo-29602: fix signed zero handling in complex constructor. (#203) https://github.com/python/cpython/commit/112ec38c15b388fe025ccb85369a584d218b1160 |
| msg288240 - (view) | Author: Mark Dickinson (mark.dickinson) *  | Date: 2017-02-20 20:57 |
New changeset 4ddd89780fdb823f427c743ea7326a3c958a2f4b by Mark Dickinson in branch 'bpo-29549-backport': bpo-29602: fix signed zero handling in complex constructor https://github.com/python/cpython/commit/4ddd89780fdb823f427c743ea7326a3c958a2f4b |
| msg288242 - (view) | Author: Mark Dickinson (mark.dickinson) *  | Date: 2017-02-20 21:14 |
New changeset c0b336e0ada74b1242b9ef10c19eb87b0a21d106 by GitHub in branch '2.7': bpo-29602: fix signed zero handling in complex constructor (#204) https://github.com/python/cpython/commit/c0b336e0ada74b1242b9ef10c19eb87b0a21d106 |
| msg288245 - (view) | Author: Mark Dickinson (mark.dickinson) *  | Date: 2017-02-20 21:50 |
New changeset 0936a00fe035e3e52c30bcbc59668dc0f519ced6 by GitHub in branch '3.5': bpo-29602: fix signed zero handling in complex constructor. (#203) (#205) https://github.com/python/cpython/commit/0936a00fe035e3e52c30bcbc59668dc0f519ced6 |
| msg288246 - (view) | Author: Mark Dickinson (mark.dickinson) *  | Date: 2017-02-20 21:59 |
New changeset d9b3cdd137239a5913de2252c3ce269e35ac63d2 by GitHub in branch '3.6': bpo-29602: fix signed zero handling in complex constructor. (#203) (#206) https://github.com/python/cpython/commit/d9b3cdd137239a5913de2252c3ce269e35ac63d2 |
| msg288247 - (view) | Author: Mark Dickinson (mark.dickinson) *  | Date: 2017-02-20 22:04 |
I'm a bit puzzled about where the commit 4ddd89780fdb823f427c743ea7326a3c958a2f4b came from, but as far as I can tell the changes to 2.7, 3.5, 3.6 and master are all okay. All fixed. Thanks for the report! |
|
| Date | User | Action | Args |
| 2022-04-11 14:58:43 | admin | set | github: 73788 |
| 2017-03-31 16:36:13 | dstufft | set | pull_requests: + pull_request889 |
| 2017-03-17 21:00:36 | larry | set | pull_requests: + pull_request620 |
| 2017-02-20 22:04:35 | mark.dickinson | set | status: open -> closed resolution: fixed messages: + msg288247
stage: patch review -> resolved |
| 2017-02-20 21:59:32 | mark.dickinson | set | messages: + msg288246 |
| 2017-02-20 21:50:51 | mark.dickinson | set | messages: + msg288245 |
| 2017-02-20 21:14:55 | mark.dickinson | set | messages: + msg288242 |
| 2017-02-20 21:13:25 | mark.dickinson | set | pull_requests: + pull_request175 |
| 2017-02-20 21:12:49 | mark.dickinson | set | pull_requests: + pull_request174 |
| 2017-02-20 21:05:33 | serhiy.storchaka | set | pull_requests: - pull_request171 |
| 2017-02-20 21:04:01 | mark.dickinson | set | pull_requests: + pull_request173 |
| 2017-02-20 20:57:57 | mark.dickinson | set | messages: + msg288240 |
| 2017-02-20 20:49:33 | serhiy.storchaka | set | pull_requests: + pull_request171 |
| 2017-02-20 20:28:17 | mark.dickinson | set | messages: + msg288236 |
| 2017-02-20 20:10:23 | mark.dickinson | set | messages: + msg288233 |
| 2017-02-20 20:09:23 | mark.dickinson | set | pull_requests: + pull_request169 |
| 2017-02-20 19:54:36 | serhiy.storchaka | set | messages: + msg288231 |
| 2017-02-20 19:27:22 | mark.dickinson | set | messages: + msg288229 |
| 2017-02-20 18:18:14 | serhiy.storchaka | set | files: + complex-constructor-from-complex2.patch |
| 2017-02-20 18:07:30 | arigo | set | messages: + msg288224 |
| 2017-02-20 18:00:10 | serhiy.storchaka | set | files: + complex-constructor-from-complex.patch keywords: + patch messages: + msg288223
stage: needs patch -> patch review |
| 2017-02-20 14:47:04 | mark.dickinson | set | messages: + msg288212 |
| 2017-02-20 14:43:14 | vstinner | set | nosy: + vstinner messages: + msg288211
|
| 2017-02-20 14:40:36 | arigo | set | messages: + msg288210 |
| 2017-02-20 14:20:26 | mark.dickinson | set | messages: + msg288208 |
| 2017-02-20 14:18:28 | mark.dickinson | set | messages: + msg288207 |
| 2017-02-20 14:04:28 | arigo | set | nosy: + arigo messages: + msg288205
|
| 2017-02-20 11:41:49 | serhiy.storchaka | set | nosy: + serhiy.storchaka
|
| 2017-02-20 11:41:15 | mark.dickinson | set | messages: + msg288196 |
| 2017-02-20 11:13:16 | mark.dickinson | set | assignee: mark.dickinson |
| 2017-02-20 11:13:02 | mark.dickinson | set | stage: needs patch messages: + msg288192 components: + Interpreter Core versions: + Python 3.5, Python 3.7 |
| 2017-02-20 09:37:16 | xiang.zhang | set | nosy: + mark.dickinson
|
| 2017-02-20 01:28:52 | steven.daprano | set | nosy: + steven.daprano
|
| 2017-02-20 00:49:52 | Tom Krauss | create | |