On Sun, 27 Mar 2005 12:48:46 +0200, =?ISO-8859-1?Q?=22Martin_v=2E_L=F6wis=22?= <[EMAIL PROTECTED]> 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 -- http://mail.python.org/mailman/listinfo/python-list