Does Python need a '>>>' operator?

Bengt Richter bokr at oz.net
Sun Apr 14 21:45:45 EDT 2002


On Sun, 14 Apr 2002 15:55:55 -0700, "Ken Peek" <Ken.Peek at SpiritSongDesigns.comNOSPAM> wrote:
[...]
>
>Thus-- my "expectation" is that 0x8000000000000000 >> 1
>is: 0x4000000000000000 (and that is the way Python now
>works for positive 'long ints'.)
>
>Given the above description of the way NEGATIVE 'long
>ints' should behave, my 'expectation' is that:
>-0x8000000000000000 >> 1 _SHOULD_ return:
>-0xC000000000000000,
>
>(_NOT_ -0x4000000000000000 as Python _NOW_ behaves.)
>
I think you are touching on an inconsistency in representation,
but I think you may be misinterpreting the hex representation as
it now is. The minus sign means that the hex is representing the
bits of the absolute value, not the bits of the negative
number in its twos complement form.

On thinking about it, I think this is ugly, though probably
convenient in the implementation. I.e., looking at the bits
of the absolute value is not usually what you really want when
you convert to hex, IMO.

All 32-bit ints are represented in hex without a sign, so
you get this ugliness:
 >>> 1<<31
 -2147483648
 >>> hex((1<<31))
 '0x80000000'
 >>> hex((1<<31)*1L)
 '-0x80000000L'

but
 >>> hex(1L<<31)
 '0x80000000L'

or perhaps more instructive, since 8 appears both ways above:
 >>> hex(15<<28)
 '0xf0000000'
 >>> hex((15<<28)*1L)
 '-0x10000000L'
 >>> hex(15L<<28)
 '0xF0000000L'

or simply
 >>> hex(-1)
 '0xffffffff'
 >>> hex(-1L)
 '-0x1L'

If hex long representation were interpreted to represent actual twos
complement bits, with the top hex digit 8-bit being extended indefinitely
to the left, you could have hex(-1L) be represented as 0xFL (which would
require that hex(15L) be represented as 0x0FL).

This might make for too much breakage, so an alternative hex prefix could
be usedm e.g., 0s instead of 0x, s meaning the the msb is interpreted as
sign, the way 32-bit ints are done now, but independent of bit width.

Using this format, 0xC would be equal to 12, but 0sC would be equal to -4
which is equal to -0x4 (which you recognize from your example). To use
0s prefix for a positive number with a msb in the 8-bit of the ms hex digit,
you'd have to prefix a hex 0 digit, e.g., 0xc == 12 == 0s0c.

Thus your -0xC000000000000000 is currently wrong as sign+hex(abs(value)),
but it could be right if we dropped the sign and used the new representation, e.g.,
0sC000000000000000 meaning that the msb was a sign bit.

>The way Python _NOW_ works, is to give a different
>behavior for the '>>' operator depending on whether you
>are working on an 'int', or a 'long int'.  This was OK
>before, because the 2 object types were treated
>differently by the language.  I thought we were trying
>_NOW_ (versions >= 2.2.x) to "unify" the behavior of
>'ints' and 'long ints'.
>
>Am I wrong?
>
Yes, I think it's not the >> operator that's at fault. It's that
0x80000000 does not numerically equal 0x80000000L, and the rest follows.
 >>> 0x80000000 == 0x80000000L
 0
 >>> 0x80000000
 -2147483648
 >>> 0x80000000L
 2147483648L

>Now, if I am right about this, then we don't really
>know if we are right shifting an 'int', or a 'long int'
We don't need to know, we just need to understand what numeric
values are really being represented internally and as hex.
The numeric values are being shifted right consistently.
It's just that negative hex longs are represented as
signed absolute values, whereas negative ints are represented
with actual bits in 8 digits. This makes ugly confusion, but
not invalid arithmetic.

>and so it would be 'useful' to have a '>>>' operator in
>this case, to guarantee that zeroes are shifted into
>the highest bit.  JAVA has this facility, why must
>Python _NOT_ have it?
Python effectively does shift in 0's for positive numbers and 1's
for negative, but if you want 0x80000000 with zeroes above, you
have to spell it 0x80000000L, 'cause 0x80000000 is a negative int
(at least on platforms with 32-bit ints. 64-bit probably works
analogously). If you want to shift in zeroes to a negative int,
you're implicitly asking for a reinterpret cast on the int number
representation from signed to unsigned (which you can accomplish
various ways).

Regards,
Bengt Richter



More information about the Python-list mailing list