On Fri, 16 Sep 2005 01:25:30 -0000, Grant Edwards <[EMAIL PROTECTED]> wrote:
>On 2005-09-15, Terry Reedy <[EMAIL PROTECTED]> 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 -- http://mail.python.org/mailman/listinfo/python-list