Hi, On Sat, Oct 15, 2011 at 1:34 PM, Derek Homeier <de...@astro.physik.uni-goettingen.de> wrote: > On 15.10.2011, at 9:42PM, Aronne Merrelli wrote: > >> >> On Sat, Oct 15, 2011 at 1:12 PM, Matthew Brett <matthew.br...@gmail.com> >> wrote: >> Hi, >> >> Continuing the exploration of float128 - can anyone explain this behavior? >> >> >>> np.float64(9223372036854775808.0) == 9223372036854775808L >> True >> >>> np.float128(9223372036854775808.0) == 9223372036854775808L >> False >> >>> int(np.float128(9223372036854775808.0)) == 9223372036854775808L >> True >> >>> np.round(np.float128(9223372036854775808.0)) == >> >>> np.float128(9223372036854775808.0) >> True >> >> >> I know little about numpy internals, but while fiddling with this, I noticed >> a possible clue: >> >> >>> np.float128(9223372036854775808.0) == 9223372036854775808L >> False >> >>> np.float128(4611686018427387904.0) == 4611686018427387904L >> True >> >>> np.float128(9223372036854775808.0) - 9223372036854775808L >> Traceback (most recent call last): >> File "<stdin>", line 1, in <module> >> TypeError: unsupported operand type(s) for -: 'numpy.float128' and 'long' >> >>> np.float128(4611686018427387904.0) - 4611686018427387904L >> 0.0 >> >> >> My speculation - 9223372036854775808L is the first integer that is too big >> to fit into a signed 64 bit integer. Python is OK with this but that means >> it must be containing that value in some more complicated object. Since you >> don't get the type error between float64() and long: >> >> >>> np.float64(9223372036854775808.0) - 9223372036854775808L >> 0.0 >> >> Maybe there are some unimplemented pieces in numpy for dealing with >> operations between float128 and python "arbitrary longs"? I could see the == >> test just producing false in that case, because it defaults back to some >> object equality test which isn't actually looking at the numbers. > > That seems to make sense, since even upcasting from a np.float64 still lets > the test fail: >>>> np.float128(np.float64(9223372036854775808.0)) == 9223372036854775808L > False > while >>>> np.float128(9223372036854775808.0) == np.uint64(9223372036854775808L) > True > > and >>>> np.float128(9223372036854775809) == np.uint64(9223372036854775809L) > False >>>> np.float128(np.uint(9223372036854775809L) == >>>> np.uint64(9223372036854775809L) > True > > Showing again that the normal casting to, or reading in of, a np.float128 > internally inevitably > calls the python float(), as already suggested in one of the parallel threads > (I think this > also came up with some of the tests for precision) - leading to different > results than > when you can convert from a np.int64 - this makes the outcome look even > weirder: > >>>> np.float128(9223372036854775807.0) - >>>> np.float128(np.int64(9223372036854775807)) > 1.0 >>>> np.float128(9223372036854775296.0) - >>>> np.float128(np.int64(9223372036854775807)) > 1.0 >>>> np.float128(9223372036854775295.0) - >>>> np.float128(np.int64(9223372036854775807)) > -1023.0 >>>> np.float128(np.int64(9223372036854775296)) - >>>> np.float128(np.int64(9223372036854775807)) > -511.0 > > simply due to the nearest np.float64 always being equal to MAX_INT64 in the > two first cases > above (or anything in between)...
Right - just for the record, I think there are four relevant problems. 1: values being cast to float128 appear to go through float64 -------------------------------------------------------------------------------------- In [119]: np.float128(2**54-1) Out[119]: 18014398509481984.0 In [120]: np.float128(2**54)-1 Out[120]: 18014398509481983.0 2: values being cast from float128 to int appear to go through float64 again ----------------------------------------------------------------------------------------------------------- In [121]: int(np.float128(2**54-1)) Out[121]: 18014398509481984 http://projects.scipy.org/numpy/ticket/1395 3: comparison to python long ints is always unequal --------------------------------------------------------------------------- In [139]: 2**63 # 2*63 correctly represented in float128 Out[139]: 9223372036854775808L In [140]: int(np.float64(2**63)) Out[140]: 9223372036854775808L In [141]: int(np.float128(2**63)) Out[141]: 9223372036854775808L In [142]: np.float128(2**63) == 2**63 Out[142]: False In [143]: np.float128(2**63)-1 == 2**63-1 Out[143]: True In [144]: np.float128(2**63) == np.float128(2**63) Out[144]: True Probably because, as y'all are saying, numpy tries to convert to np.int64, fails, and falls back to an object array: In [145]: np.array(2**63) Out[145]: array(9223372036854775808L, dtype=object) In [146]: np.array(2**63-1) Out[146]: array(9223372036854775807L) 4 : any other operation of float128 with python long ints fails -------------------------------------------------------------------------------------- In [148]: np.float128(0) + 2**63 --------------------------------------------------------------------------- TypeError Traceback (most recent call last) /home/mb312/<ipython-input-148-5cc20524867d> in <module>() ----> 1 np.float128(0) + 2**63 TypeError: unsupported operand type(s) for +: 'numpy.float128' and 'long' In [149]: np.float128(0) - 2**63 --------------------------------------------------------------------------- TypeError Traceback (most recent call last) /home/mb312/<ipython-input-149-4d5064ca1f61> in <module>() ----> 1 np.float128(0) - 2**63 TypeError: unsupported operand type(s) for -: 'numpy.float128' and 'long' In [150]: np.float128(0) * 2**63 --------------------------------------------------------------------------- TypeError Traceback (most recent call last) /home/mb312/<ipython-input-150-ee0123db30da> in <module>() ----> 1 np.float128(0) * 2**63 TypeError: unsupported operand type(s) for *: 'numpy.float128' and 'long' In [151]: np.float128(0) / 2**63 --------------------------------------------------------------------------- TypeError Traceback (most recent call last) /home/mb312/<ipython-input-151-cbbf8ad624fa> in <module>() ----> 1 np.float128(0) / 2**63 TypeError: unsupported operand type(s) for /: 'numpy.float128' and 'long' Thanks for the feedback, Best, Matthew _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion