On 15.10.2011, at 9:42PM, Aronne Merrelli wrote:
>
> On Sat, Oct 15, 2011 at 1:12 PM, Matthew Brett <[email protected]>
> 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
[email protected]
http://mail.scipy.org/mailman/listinfo/numpy-discussion