float complex discussion

16 views
Skip to first unread message

Tom Krauss

unread,
Jan 21, 2017, 11:31:46 AM1/21/17
to pytho...@googlegroups.com
I un-skipped the "test_complex_types" function in c/test_c.py, and the first thing it does in creating a new primitive type is try to access key '_Complex float' in the PRIMITIVE_TYPES dict of ctype types. We could try to add the key, but what value?

My ctypes does not have a c_complex type, it was a feature that was "postponed" in ctypes in 2013 since libfft did not support C99 complex at the time (http://bugs.python.org/issue16899). 

I'll post on that thread and see if it could be reopened... any advice LMK.

Cheers,
  Tom

Armin Rigo

unread,
Jan 21, 2017, 12:49:26 PM1/21/17
to pytho...@googlegroups.com
Hi Tom,

On 21 January 2017 at 17:31, Tom Krauss <thomas....@gmail.com> wrote:
> I un-skipped the "test_complex_types" function in c/test_c.py, and the first
> thing it does in creating a new primitive type is try to access key
> '_Complex float' in the PRIMITIVE_TYPES dict of ctype types. We could try to
> add the key, but what value?

Is there some confusion between a <ctype object> of cffi, and the
ctypes standard module of Python? Nothing in the c/ directory depends
on the latter in any way. (The exception is the helper
find_and_load_library() in c/test_c.py, using
ctypes.util.find_library().)


A bientôt,

Armin.

Tom Krauss

unread,
Jan 29, 2017, 1:14:58 PM1/29/17
to python-cffi
Hello Armin,

Sorry for the late response!

Yes, I am confused about a lot of things :-). I don't understand the code architecture enough yet to even comprehend your question. But from the response, it sounds like I was heading down the wrong path.

The ctypes issue has been re-opened, FWIW.

Regards,
  Tom

Armin Rigo

unread,
Jan 29, 2017, 5:07:35 PM1/29/17
to pytho...@googlegroups.com
Hi Tom,

On 29 January 2017 at 19:14, Tom Krauss <t...@kraussfamily.org> wrote:
> Yes, I am confused about a lot of things :-). I don't understand the code
> architecture enough yet to even comprehend your question.

Let me try to rephrase, just in case. I am saying that ctypes has,
mostly, nothing to do with cffi. The task of adding support for the C
complex types in cffi, and the task of adding support for the C
complex types in ctypes, are two unrelated projects. The only common
point between these two projects is that they both depend on libffi:
each project was impossible to do before libffi grew support.


A bientôt,

Armin.

Tom Krauss

unread,
Feb 12, 2017, 8:18:21 PM2/12/17
to pytho...@googlegroups.com
STATUS UPDATE:

Down to just two more test failures in c/test_c.py:test_complex_types()

  1)   assert repr(complex(cast(p, -0j))) == '-0j'
  2)   assert complex(cast(p, '\x09')) == 9.0

I haven't looked at 2) yet but 1) is failing due to python's behavior: the answer should be -0j, it is returning 0j instead.

The issue is in complexobject.c: complex_new, at the end where it does this:
    if (cr_is_complex) {
        ci.real += cr.imag;
    }
    return complex_subtype_from_doubles(type, cr.real, ci.real);

cr.imag is appropriately "-0" still, but after this statement, ci.real is just 0. The resulting returned object is just 0j, not -0j.

Any ideas how to resolve this without changing python?





A bientôt,

Armin.

--
-- python-cffi: To unsubscribe from this group, send email to python-cffi+unsubscribe@googlegroups.com. For more options, visit this group at https://groups.google.com/d/forum/python-cffi?hl=en
---
You received this message because you are subscribed to the Google Groups "python-cffi" group.
To unsubscribe from this group and stop receiving emails from it, send an email to python-cffi+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Armin Rigo

unread,
Feb 13, 2017, 2:43:24 AM2/13/17
to pytho...@googlegroups.com
Hi Tom,

On 13 February 2017 at 02:18, Tom Krauss <thomas....@gmail.com> wrote:
> I haven't looked at 2) yet but 1) is failing due to python's behavior: the
> answer should be -0j, it is returning 0j instead.

It looks like a Python bug. It also occurs with subclasses of complex:

class C(complex): pass
print complex(C(-0j)) # 0j

including the numpy classes:

print numpy.complex64(-0j) # -0j
print complex(numpy.complex64(-0j)) # 0j

So I wouldn't try to force the right answer (if it is possible at
all), but instead just report this to http://bugs.python.org, and
comment out that line in the cffi test with a reference to your new
issue.


A bientôt,

Armin.

Armin Rigo

unread,
Feb 13, 2017, 2:47:24 AM2/13/17
to pytho...@googlegroups.com
Re-hi,

On 13 February 2017 at 02:18, Tom Krauss <thomas....@gmail.com> wrote:
> STATUS UPDATE:
>
> Down to just two more test failures in c/test_c.py:test_complex_types()

Oh, and I'm sure you don't forget it, but the most important part is
*calls* that include or return a complex number :-) There are no
tests so that so far. Look at the various test_call_function_NUMBER.


A bientôt,

Armin.

Armin Rigo

unread,
Feb 13, 2017, 3:56:27 AM2/13/17
to pytho...@googlegroups.com
Hi again,

On 13 February 2017 at 08:42, Armin Rigo <armin...@gmail.com> wrote:
> It looks like a Python bug. It also occurs with subclasses of complex:
>
> class C(complex): pass
> print complex(C(-0j)) # 0j
>
> including the numpy classes:
>
> print numpy.complex64(-0j) # -0j
> print complex(numpy.complex64(-0j)) # 0j

On CPython 3.5.2 it changes, but it is not better at all. You get
some bizarre behavior that doesn't make sense (see below). I think
that the best CFFI should do is never worry about the signed zeroes in
the real and imaginary parts, and treat them as equivalent. (You can
still open an issue on CPython if you feel like it.)

class C(complex): pass
C(-0j) # (-0+0j)
complex(-0j) # (-0-0j)
complex(-0-0j) # 0j

My favourite part is this, which shows inconsistency between the repr
output and the constant input:

complex(-0j) # (-0-0j)
-0-0j # 0j

For extra fun, you can get closer to (-0-0j) by using 0.0 instead of
0, but not all the way:

-0.0-0j # (-0+0j)


A bientôt,

Armin.

Armin Rigo

unread,
Feb 13, 2017, 3:59:16 AM2/13/17
to pytho...@googlegroups.com
Re-hi,

On 13 February 2017 at 09:55, Armin Rigo <armin...@gmail.com> wrote:
> For extra fun, you can get closer to (-0-0j) by using 0.0 instead of
> 0, but not all the way:
>
> -0.0-0j # (-0+0j)

Nope, you can:

-0j # (-0-0j)


Armin

Tom Krauss

unread,
Feb 13, 2017, 6:23:33 AM2/13/17
to pytho...@googlegroups.com
Hi Armin,
I'm just happy to have found a real, honest to goodness bug in python. This is a first for me! 
For my next steps I will plan on filing a python issue for that (once I reproduce on 3.5 as you have), and add some tests for calls that return a complex number.
Regards,
  Tom


Armin Rigo

unread,
Feb 13, 2017, 3:59:19 PM2/13/17
to pytho...@googlegroups.com
Hi Tom,

On 13 February 2017 at 12:23, Tom Krauss <thomas....@gmail.com> wrote:
> I'm just happy to have found a real, honest to goodness bug in python. This
> is a first for me!

You should work with us on the Python 3.5 support in PyPy next. We're
finding such bugs at a high rate :-) There are all obscure but
potentially serious in some corner cases, like this one about
complexes.


A bientôt,

Armin.

Tom Krauss

unread,
Feb 19, 2017, 9:00:28 PM2/19/17
to pytho...@googlegroups.com
Progress:
 - filed an issue for the -0j test point (http://bugs.python.org/issue29602) and commented that test out
 - got the other tests to pass:
        assert complex(cast(p, b'\x09')) == 9.0
        assert complex(cast(p, u+'\x09')) == 9.0
  by setting the "real" part to the converted string value. 


Tom Krauss

unread,
Feb 26, 2017, 8:21:26 PM2/26/17
to pytho...@googlegroups.com
Progress:
 - added a test for a C function that returns a "float _Complex".

Plan:
 - support for "double _Complex"
 - merge from mainline into my branch
 - more testing

Reply all
Reply to author
Forward
0 new messages