Description of problem: This is a tracking bug for python-cffi-1.11.5-1, which currently fails to build on little endian ppc64 due to rounding issues. ____________________________ TestNewFFI1.test_float ____________________________ self = <testing.cffi1.test_new_ffi_1.TestNewFFI1 object at 0x7fffb993d630> def test_float(self): p = ffi.new("float[]", [-2, -2.5]) assert p[0] == -2.0 assert p[1] == -2.5 p[1] += 17.75 assert p[1] == 15.25 # p = ffi.new("float*", 15.75) assert p[0] == 15.75 py.test.raises(TypeError, int, p) py.test.raises(TypeError, float, p) p[0] = 0.0 assert bool(p) is True # p = ffi.new("float*", 1.1) f = p[0] assert f != 1.1 # because of rounding effect assert abs(f - 1.1) < 1E-7 # INF = 1E200 * 1E200 assert 1E200 != INF p[0] = 1E200 > assert p[0] == INF # infinite, not enough precision E assert 21918092.0 == inf testing/cffi1/test_new_ffi_1.py:474: AssertionErro ______________________________ TestFFI.test_float ______________________________ self = <testing.cffi0.test_ffi_backend.TestFFI object at 0x7fffb97dd2b0> def test_float(self): ffi = FFI(backend=self.Backend()) p = ffi.new("float[]", [-2, -2.5]) assert p[0] == -2.0 assert p[1] == -2.5 p[1] += 17.75 assert p[1] == 15.25 # p = ffi.new("float*", 15.75) assert p[0] == 15.75 py.test.raises(TypeError, int, p) py.test.raises(TypeError, float, p) p[0] = 0.0 assert bool(p) is True # p = ffi.new("float*", 1.1) f = p[0] assert f != 1.1 # because of rounding effect assert abs(f - 1.1) < 1E-7 # INF = 1E200 * 1E200 assert 1E200 != INF p[0] = 1E200 > assert p[0] == INF # infinite, not enough precision E AssertionError testing/cffi0/backend_tests.py:416: AssertionError ______________________________ test_complex_types ______________________________ def test_complex_types(): INF = 1E200 * 1E200 for name in ["float", "double"]: p = new_primitive_type(name + " _Complex") assert bool(cast(p, 0)) is False assert bool(cast(p, INF)) assert bool(cast(p, -INF)) assert bool(cast(p, 0j)) is False assert bool(cast(p, INF*1j)) assert bool(cast(p, -INF*1j)) # "can't convert complex to float", like CPython's "float(0j)" py.test.raises(TypeError, int, cast(p, -150)) py.test.raises(TypeError, long, cast(p, -150)) py.test.raises(TypeError, float, cast(p, -150)) assert complex(cast(p, 1.25)) == 1.25 assert complex(cast(p, 1.25j)) == 1.25j assert complex(cast(p, complex(0,INF))) == complex(0,INF) assert complex(cast(p, -INF)) == -INF if name == "float": assert complex(cast(p, 1.1j)) != 1.1j # rounding error > assert complex(cast(p, 1E200+3j)) == INF+3j # limited range E AssertionError: assert (21918092+3j) == (inf + 3j) E + where (21918092+3j) = complex(<cdata 'float _Complex' (21918092+3j)>) E + where <cdata 'float _Complex' (21918092+3j)> = cast(<ctype 'float _Complex'>, (1e+200 + 3j)) c/test_c.py:211: AssertionError _______________________________ test_float_types _______________________________ def test_float_types(): INF = 1E200 * 1E200 for name in ["float", "double"]: p = new_primitive_type(name) assert bool(cast(p, 0)) is False # since 1.7 assert bool(cast(p, -0.0)) is False # since 1.7 assert bool(cast(p, 1e-42)) is True assert bool(cast(p, -1e-42)) is True assert bool(cast(p, INF)) assert bool(cast(p, -INF)) assert bool(cast(p, float("nan"))) assert int(cast(p, -150)) == -150 assert int(cast(p, 61.91)) == 61 assert long(cast(p, 61.91)) == 61 assert type(int(cast(p, 61.91))) is int assert type(int(cast(p, 1E22))) is long assert type(long(cast(p, 61.91))) is long assert type(long(cast(p, 1E22))) is long py.test.raises(OverflowError, int, cast(p, INF)) py.test.raises(OverflowError, int, cast(p, -INF)) assert float(cast(p, 1.25)) == 1.25 assert float(cast(p, INF)) == INF assert float(cast(p, -INF)) == -INF if name == "float": assert float(cast(p, 1.1)) != 1.1 # rounding error > assert float(cast(p, 1E200)) == INF # limited range E AssertionError: assert 21918092.0 == inf E + where 21918092.0 = float(<cdata 'float' 21918092.0>) E + where <cdata 'float' 21918092.0> = cast(<ctype 'float'>, 1e+200) c/test_c.py:182: AssertionError
Buf filed upstream: https://bitbucket.org/cffi/cffi/issues/361/tests-fail-due-to-rounding-and-complex
Upstream seems to think this is a problem with glibc, so assigning accordingly.
(In reply to John Dulaney from comment #2) > Upstream seems to think this is a problem with glibc, so assigning > accordingly. I don't see any notes that this is a glibc or gcc problem. #include <stdio.h> #include <stdlib.h> #include <math.h> #include <assert.h> int main (void) { float pf, inff; pf = 1e200f; inff = 1e200f * 1e200f; assert (pf == inff); return 0; } gcc -O0 -g3 -o math-test ./math-test.c ./math-test.c: In function ‘main’: ./math-test.c:10:3: warning: floating constant exceeds range of ‘float’ [-Woverflow] pf = 1e200f; ^~ ./math-test.c:11:3: warning: floating constant exceeds range of ‘float’ [-Woverflow] inff = 1e200f * 1e200f; ^~~~ ./math-test.c:11:3: warning: floating constant exceeds range of ‘float’ [-Woverflow] As expected, because they all overflow the range of float. ./math-test Does not assert. Therefore pf is infinity. Something is wrong with FFI's conversion of the value to the type. I also do not see where anyone says this is a glibc error. Though as noted there might still be a compiler issue, but that hasn't been ruled out. You need to work out the issue in more detail.
This bug appears to have been reported against 'rawhide' during the Fedora 29 development cycle. Changing version to '29'.
The tests are commented out. I will run them again, but skip float tests on ppc64le for now. I think after https://fedoraproject.org/wiki/Changes/PPC64LE_Float128_Transition this might no longer be a problem.
(In reply to Carlos O'Donell from comment #3) > I also do not see where anyone says this is a glibc error. > > Though as noted there might still be a compiler issue, but that hasn't been > ruled out. See the current conversation on the BitBucket issue. I don't think the conclusion is "This is a GCC bug", but more like "Pleeease, we are out of our depth here. Would somebody from the around the GCC come and tell us what's going on?".
Setting this to low priority. It would be great if someone else would get to this earlier than we can. If that's your case, please assign the bug to yourself (and adjust priority accordingly).
Can this issue be related to the test_ctypes failure https://bugzilla.redhat.com/show_bug.cgi?id=1540995 which was caused by this GCC fix? https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88892
(In reply to Victor Stinner from comment #8) > Can this issue be related to the test_ctypes failure > https://bugzilla.redhat.com/show_bug.cgi?id=1540995 which was caused by this > GCC fix? https://gcc.gnu.org/bugzilla/show_bug.cgi?id=88892 Do you mean “fixed by” and not ”caused by”? Yes, since float types are involved in both cases, this is a possibility. I have not investigated this bug here because the reproducer in the description does not look very self-contained by me, but then I don't know anything about python-cffi.
Oops, I mean caused by the GCC bug. This bug now fixed in Rawhide.
Seems to be OK on the recent version.