2.3 -> 2.4: long int too large to convert to int
bokr at oz.net
Fri Sep 16 10:53:56 CEST 2005
On Fri, 16 Sep 2005 01:25:30 -0000, Grant Edwards <grante at visi.com> wrote:
>On 2005-09-15, Terry Reedy <tjreedy at udel.edu> wrote:
>>>I give up, how do I make this not fail under 2.4?
>>> I get an OverflowError: long int too large to convert to int
>>> ioctl() is expecting a 32-bit integer value, and 0xc0047a80 has
>>> the high-order bit set. I'm assuming Python thinks it's a
>>> signed value. How do I tell Python that 0xc0047a80 is an
>>> unsigned 32-bit value?
>> In 2.3 and before, you get this:
>I don't particular care how Python prints the value -- I just
>want that value passed to the function I'm calling.
I do care, dang it. IMIFO (in my increasingly frustrated opinion ;-)
one ought to be able to write literals for negative integers.
A simple variation on 0x... coul be 0h... where what follows 0h is
base-16-complement, which turns out to be 0hfc0047a80 for the negative
number you want, and would be 0h0c0047a80 if you wanted the positive number
with the same least significant bits.
>> In 2.4, positive hex literals are treated as positive numbers, and that is
>> your problem: your literal is greater than the largest int and hence gets
>> stored as long int.
>I knew that, I just couldn't come up with a good way to fix it.
IMO you shouldn't have to fight it.
>> I would try -1073448320 as the arg.
>That should work, but it's kind of lame (no offense).
Yes, it is lame ;-)
see more on the notation (of which hex is only the particular base-16 case)
(It doesn't show in the examples, but unfortunately the code has a bug that I fixed
in a later post,
the encoding of -1073448320 would be
>>> from ut.basecompl import basecompl as bc, bcdecode as bcd
>>> '0h'+bc(-1073448320, 16)
or you could use other bases with 0b<base>. prefix:
>>> '0b2.'+bc(-1073448320, 2)
>>> '0b8.'+bc(-1073448320, 8)
>>> '0b16.'+bc(-1073448320, 16)
>>> '0b10.'+bc(-1073448320, 10)
-1073448320 note the correspondence to previous line for base 10 ;-)
repeating the "sign digit" doesn't change the decoded value:
irrespective of the base:
>>> bcd('98926551680', 10)
>>> bcd('99999999999999998926551680', 10)
>>> bcd('fc0047a80', 16)
>>> bcd('fffffffffffffffffffc0047a80', 16)
>ioctl values are always, always written in hex. A block of
>ioctl values is generally assigned to a particular driver such
>that the high order N (is it 4 oe 5?) hex digits are unique to
>that driver. Writing the value in decimal is going to
>completely confuse anybody looking at the code.
>I rather like the other suggestion of writing a function that
>accepts 0x<whatever> and returns the appropriate integer value.
Sure, but there's no reason we shouldn't be allowed to specify a constant
as a literal IMO.
>Another poster suggested a solution using struct. Here's my
>solution (which assume python integers are represented in 2's
> if i & 0x80000000:
> i = -((i^0xffffffff)+1)
> return i
Do you think it's PEP-able, or should I quit being obnoxious ;-)
I think str.mod format like %x except %<width>.<base>b would make it
easy to write '0h%08b.16' % a_signed_integer and get something both
readable and inputtable as a constant. (0h.<the rest> would be short
for 0b16.<the rest>) BTW, %b (or %B for uppercase) could default to base 16.
The ouput would only be as wide as necessary, with the leading digit
guaranteed 0 or f (which is 0 or <base-1> in the general case).
More information about the Python-list