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)... Cheers, Derek _______________________________________________ NumPy-Discussion mailing list NumPy-Discussion@scipy.org http://mail.scipy.org/mailman/listinfo/numpy-discussion