long int behaviour
Tim Peters
tim.one at home.com
Thu Mar 1 00:09:25 EST 2001
[Timothy Grant]
> ...
> Given the following experimenting...
>
> >>> hex(4294965248L)
> '0xFFFFF800L'
> >>> hex(~4294965248L)
> '-0xFFFFF801L'
> >>>
>
> The first output is what I would expect, however, I would have
> expected the second output to be
>
> 0x000007FFL
>
> It appears to be something to do with two's complement storage,
> but I'm at a loss as to why my expectations were so incorrect.
Take heart! Your expectations weren't born incorrect, they were made
incorrect, by a world of evil languages promulgating their blasphemous
treachery that integers are finite <wink>.
Python does store longs in 2's-comp form, but remember that Python longs are
unbounded: a long less than 0 has a (conceptually) infinite string of
leading 1 bits, just as a long >= 0 has an infinite string of leading 0 bits.
It's easy to show you an infinite string of leading 0 bits: we just ignore
them. That infinite string of leading 1 bits isn't so easy to hide, though!
You've been further warped into believing that 32 bits is somehow a "natural"
size for an int. If that's what you believe, you can force the issue:
>>> hex(~4294965248L & (2L**32 - 1))
'0x7FFL'
>>>
That is, by masking your input with a string of 32 low-order 1-bits, the
infinite string of leading 1 bits goes away, leaving the output you expected.
Or, if you're lucky enough to believe that ints have 101 bits, similarly:
>>> hex(~4294965248L & (2L**101 - 1))
'0x1FFFFFFFFFFFFFFFFF000007FFL'
>>>
So that's the trick: to represent the infinite by the finite, you either
need a convention, or you need to throw an infinite amount of info away. The
"-" in '-0xFFFFF801L' is Python's convention for compressing the unbounded
string of sign bits in such a way that no info is lost:
>>> eval(hex(~4294965248L)) == ~4294965248L
1
>>>
next-step:-infinite-memory-ly y'rs - tim
More information about the Python-list
mailing list