Does Python need a '>>>' operator?

Bengt Richter bokr at oz.net
Tue Jun 11 12:01:04 CEST 2002


On Mon, 10 Jun 2002 14:11:31 +0300 (IDT), Beni Cherniavksy <cben at techunix.technion.ac.il> wrote:

>On 2002-06-10, Ken Seehof wrote:
>
>> Beni Cherniavsky <cben at tx.technion.ac.il> wrote:
>> > I just got another idea: use 0x1234 for 0-filled numbers and 1xABCD for
>> > 1-filled ones.  That way you impose no restrictions on what follows the
If there are no restrictions, 1x7 must have a meaning.
What do you want it to mean?

>> > prefix and keep backward compatibility.  0xFFFFFFFF stays a 2^n-1
>> > _positive_ number, as it should be.  The look of 1x is weird at first but
>> > it is very logical...
[...]
Well, consider the logic of a different format: The prefix is always 0h
and the hex data part always includes just enough duplicated-as-necessary
sign bits to make the first hex digit 0 for positive numbers and f for negative.

IOW, you could pretend to store the integer value in a 4*k bit wide register,
where k is just large enough so the top 4 bits are either all 0 or all 1.
Then just print with k hex digits for the data.

A previous version had a bug for sure, and I never got around to fixing it
and posting it to answer Martin's last objection. Still no guarantees, but
the version below illustrates the format...

[Martin]
>Unfortunately, you cannot represent such a number in hex, atleast not
>under any of the usual conventions: the convention is that you can
>strip infinitely many leading zeroes, but stripping off infinitely many
>leading ones is confusing.
>
With Greg Ewing's suggestion (to make sure leading hex digits are 0 or F rather
than just having 0 or 1 in the msb of the first hex digit to indicate sign, as
I had first suggested), I think it can be done very clearly:

Pretend that you have printed with extra width (e.g., infinite) and just strip
leading duplicate 0's or F's from the left of the data part until you have either
0h0.... or 0hF....

This illustrates the format, anyway:

 >>> def newhex(n, width=0):
 ...     """prints hex bits with leading 0 for positive and leading f for negative"""
 ...     if n<0: nh = ((~long(n))<<4)&long(n)
 ...     else:   nh = (( long(n))<<4)&(~long(n))
 ...     nh = len('%x' % nh)
 ...     ret =  '0h%s%x' % ((n>0 and '0' or ''),long(n)&((1L<<(nh*4))-1))
 ...     if width>len(ret):
 ...         return '0h'+ret[2]*(width-len(ret))+ret[2:]
 ...     else:
 ...         return ret
 ...
 >>> for i in range(12): print '%16s%16s' % (newhex( 1L<<i   ), newhex(-1L<<i   ))
 ...
             0h01             0hf
             0h02            0hfe
             0h04            0hfc
             0h08            0hf8
            0h010            0hf0
            0h020           0hfe0
            0h040           0hfc0
            0h080           0hf80
           0h0100           0hf00
           0h0200          0hfe00
           0h0400          0hfc00
           0h0800          0hf800
 >>>
 >>> for i in range(12): print '%16s%16s' % (newhex( 7L<<i   ), newhex(-7L<<i   ))
 ...
             0h07            0hf9
             0h0e            0hf2
            0h01c           0hfe4
            0h038           0hfc8
            0h070           0hf90
            0h0e0           0hf20
           0h01c0          0hfe40
           0h0380          0hfc80
           0h0700          0hf900
           0h0e00          0hf200
          0h01c00         0hfe400
          0h03800         0hfc800
 >>> for i in range(12): print '%16s%16s' % (newhex( 1L<<i,5), newhex(-1L<<i,5))
 ...
            0h001           0hfff
            0h002           0hffe
            0h004           0hffc
            0h008           0hff8
            0h010           0hff0
            0h020           0hfe0
            0h040           0hfc0
            0h080           0hf80
           0h0100           0hf00
           0h0200          0hfe00
           0h0400          0hfc00
           0h0800          0hf800
 >>> for i in range(12): print '%16s%16s' % (newhex( 1L<<i,10), newhex(-1L<<i,10))
 ...
       0h00000001      0hffffffff
       0h00000002      0hfffffffe
       0h00000004      0hfffffffc
       0h00000008      0hfffffff8
       0h00000010      0hfffffff0
       0h00000020      0hffffffe0
       0h00000040      0hffffffc0
       0h00000080      0hffffff80
       0h00000100      0hffffff00
       0h00000200      0hfffffe00
       0h00000400      0hfffffc00
       0h00000800      0hfffff800
 >>> for n in xrange(-32,33,4): print '%3d %16X %s' % (n,n,newhex(n))
 ...
 -32         FFFFFFE0 0hfe0
 -28         FFFFFFE4 0hfe4
 -24         FFFFFFE8 0hfe8
 -20         FFFFFFEC 0hfec
 -16         FFFFFFF0 0hf0
 -12         FFFFFFF4 0hf4
  -8         FFFFFFF8 0hf8
  -4         FFFFFFFC 0hfc
   0                0 0h0
   4                4 0h04
   8                8 0h08
  12                C 0h0c
  16               10 0h010
  20               14 0h014
  24               18 0h018
  28               1C 0h01c
  32               20 0h020

After 0h0 or 0hf there are no restrictions to the hex that follows (or doesn't),
and the abstract integer value is unambiguously determinable.

Regards,
Bengt Richter



More information about the Python-list mailing list