2.3 -> 2.4: long int too large to convert to int
Bengt Richter
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?
>>>
>>> fcntl.ioctl(self.dev.fileno(),0xc0047a80,struct.pack("HBB",0x1c,0x00,0x00))
>>>
>>> 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:
>>>>> 0xc0047a80
>> -1073448320
>
>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)
http://groups.google.co.uk/group/comp.lang.python/msg/2c411ca9251774dc
(It doesn't show in the examples, but unfortunately the code has a bug that I fixed
in a later post,
http://groups.google.co.uk/group/comp.lang.python/msg/359927a23eb15b3e
the encoding of -1073448320 would be
>>> from ut.basecompl import basecompl as bc, bcdecode as bcd
>>> '0h'+bc(-1073448320, 16)
'0hfc0047a80'
or you could use other bases with 0b<base>. prefix:
>>> '0b2.'+bc(-1073448320, 2)
'0b2.1000000000001000111101010000000'
>>> '0b8.'+bc(-1073448320, 8)
'0b8.70001075200'
>>> '0b16.'+bc(-1073448320, 16)
'0b16.fc0047a80'
>>> '0b10.'+bc(-1073448320, 10)
'0b10.98926551680'
-1073448320 note the correspondence to previous line for base 10 ;-)
>>> bcd('0101',2)
5
>>> bcd('1101',2)
-3
repeating the "sign digit" doesn't change the decoded value:
>>> bcd('11111111111111111101',2)
-3
>>> bcd('00000000000000000101',2)
5
irrespective of the base:
>>> bcd('98926551680', 10)
-1073448320L
>>> bcd('99999999999999998926551680', 10)
-1073448320L
>>> bcd('fc0047a80', 16)
-1073448320L
>>> bcd('fffffffffffffffffffc0047a80', 16)
-1073448320L
>
>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
>compliment binary):
>
>def ioctlValue(i):
> 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).
</rant>
Regards,
Bengt Richter
More information about the Python-list
mailing list