Does Python need a '>>>' operator?
Bengt Richter
bokr at oz.net
Mon Apr 15 02:06:12 EDT 2002
On Sun, 14 Apr 2002 20:00:54 -0700, David Eppstein <eppstein at ics.uci.edu> wrote:
>In article <a9dbc9$bge$0 at 216.39.172.122>, bokr at oz.net (Bengt Richter)
>wrote:
>
>> All 32-bit ints are represented in hex without a sign, so
>
>This signed-unsigned confusion bit me when I needed a routine to count
>the nonzero bits of some input. Normally one would write
>
> def popCount(x):
> count = 0
> while x:
> count += 1
> x &= x - 1
>
>but of course this gets into an infinite loop when the high bit is set.
>Arguably, this is the correct behavior: a negative number in 2's
>complement should be thought of as having an infinite sequence of 1-bits.
>
>But in my case, my input didn't ever have the high bit set, and a good
>thing too, or I would have gotten ValueError when I tried
>int(hexstring,16).
>The reason I was getting into trouble anyway was because of the way
>right-shifting can change sign:
^^^^^ ITYM left?
>
>>>> 0x40000000<<1
>-2147483648
>
>This is inconsistent with int-long unification. In fact, I think it is
>a bug. The answer should, of course, be 2147483648L, just as you would
>get by multiplying by 2 instead of shifting.
>
I think you're right. I wonder how much code will actually break.
>>> 0x040000000<<1
-2147483648
but
>>> 0x040000000<<1L
2147483648L
but**2
>>> 0x80000000>>1L
-1073741824L
It makes perfect sense when you know what's happening ;-/
With int-long unification, arguably 0x80000000 written plain should be promoted
to 0x8000000L, and you should have to write -0x80000000 if that's what you mean,
unless we distinguish by msb as 0s80000000 negative vs 0s080000000 positive. Maybe 0h is
a better prefix for hex: 0h80000000 + 0h080000000 => 0, and 0hf + 0h1 => 0
I like this representation better than sign+hex(magnitude), because you can read
the actual bits (assuming twos complement representation). The analogous binary
representation would have a mandatory 0 msb for positive numbers too:
>>> binstr(0x40000000<<1)
'110000000000000000000000000000000'
>>> binstr(0x40000000<<1L)
'010000000000000000000000000000000'
>>> binstr(0x80000000>>1L)
'11000000000000000000000000000000'
note that that last line didn't need to be
'111000000000000000000000000000000'
in fact, it could have been
'1000000000000000000000000000000'
guess maybe I could fix that, but I think I like the symmetry in
>>> for n in xrange(8): print '%-6s%-6s' % (binstr(n), binstr(-n))
...
0 0
01 11
010 110
011 101
0100 1100
0101 1011
0110 1010
0111 1001
Regards,
Bengt Richter
More information about the Python-list
mailing list