How to get rid of FutureWarning: hex/oct constants...

Bengt Richter bokr at oz.net
Sun Mar 27 19:44:22 EST 2005


On Sun, 27 Mar 2005 12:48:46 +0200, =?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?= <martin at v.loewis.de> wrote:

>Bengt Richter wrote:
>>  >>> hex(-2*0x40000000+0x40047a80)
>>  __main__:1: FutureWarning: hex()/oct() of negative int will return a signed string in Python 2.4
>>   and up
>>  '0xc0047a80'
>> 
>> That "signed string" is a unary minus expression using an absolute value forced by the inadequacy
>> of the literal representation syntax.
>> IOW, IMO '-' + hex_literal_of(abs(x)) is not a decent hex_literal_of(-x) !!
>
>This has been discussed over and over, but since you bring it up again:
It seems you have a different concept of "this" than I ;-)
>
>There are no hex literals for negative numbers, just as there are no
>decimal literals for negative number. A literal, by nature, in any
>base, is non-negative.

You are talking about what _is_, not what _can be_  ;-)

IMO a literal is a source-context-compatible string representing an abstract value
(which typically has an alternate representation in the running-program context).

AFAIK there is no law against representing negative numbers as such with whatever
literal spellings are deemed useful.
>
>If you disagree: Is 0xFFF6 a positive or a negative number?

That is conventionally a positive number, because the python 2.4 hex syntax
is interpreted that way, as it should be now. With a leading 16x prefix instead of 0x
the rules would/could change. See below.

I am trying to propose an alternate (additional, not replacement) syntax, which
you could call base-complement. The base is specified by a prefixed <base>x where
<base> is encoded in decimal. Zero is not a legal base, so there is no problem
recognizing current hex literals.

The digits following <base>x result from the numeric value's being encoded with
the base radix, and the most significant _must_ be zero or base-1 and may be repeated
leftwards as far as desired without changing the value, which is computed by something like:

For digits on the right side (following the <base>x):
 >>> def bcdecode(s, B=10, digits='0123456789abcdefghijklmnopqrstuvwxyz'):
 ...     if s == digits[0]: return 0
 ...     acc = s[0].lower() == digits[B-1] and -B**len(s) or 0
 ...     for i, c in enumerate(s[::-1]):
 ...         acc += digits.index(c)*B**i
 ...     return acc
 ...

For the whole literal (which you need, unless you are assuming you know the base
and that first digits are sign or sign leftwards-replications according to base-complement convention)

 >>> def blitdec(s):
 ...     xpos = s.lower().index('x')
 ...     base = int(s[:xpos])
 ...     return bcdecode(s[xpos+1:], base)
 ...
 >>> blitdec('2x011')
 3
 >>> blitdec('2x00000011')
 3
 >>> blitdec('2x101')
 -3
 >>> blitdec('2x11111101')
 -3
 >>> blitdec('16x0fff6')
 65526
 >>> blitdec('16xffff6')
 -10
 >>> hex(blitdec('16x0fff6'))
 '0xfff6'
 >>> hex(blitdec('16xffff6'))
 '-0xa'
Urk! ;-/
For backwards compatibility, hex will have to do that, but there IMO there should be
a base-complement output format available too, so e.g., (to give it a name)
   baselit(blitdec('16xffff6'), 16) => '16xf6' #(normalized to single sign digit unless explicitly formatted)

BTW,
 >>> blitdec('8x03')
 3
 >>> blitdec('8x73')
 -5
 >>> blitdec('10x03')
 3
 >>> blitdec('10x93')
 -7

The point is a bit-visualization-friendly literal representation (when desired,
and for which you'd normally use base 2, 8, or 16 ;-) of all integers.

And also it could be nice to be able to write (impossible now)
 >>> compiler.parse('x=16xffff6','single')

and get
 Module(None, Stmt([Assign([AssName('x', 'OP_ASSIGN')], Const(-10))]))

instead of (the result of what you have to write now)
 Module(None, Stmt([Assign([AssName('x', 'OP_ASSIGN')], UnarySub(Const(10)))]))


BTW, I see the code above  needs some cleaning and another .lower() or two
but I am too lazy to fix or optimize, and the corresponding
literal-formatting code is left as an exercise ;-)

Regards,
Bengt Richter



More information about the Python-list mailing list