2's complement conversion. Is this right?

Bob Greschke bob at passcal.nmt.edu
Fri Apr 18 23:26:58 CEST 2008


On 2008-04-18 14:37:21 -0600, Ross Ridge 
<rridge at caffeine.csclub.uwaterloo.ca> said:

> Bob Greschke  <bob at passcal.nmt.edu> wrote:
>> I'm reading 3-byte numbers from a file and they are signed (+8 to 
>> -8million).  This seems to work, but I'm not sure it's right.
>> 
>> # Convert the 3-characters into a number.
>> Value1, Value2, Value3 = unpack(">BBB", Buffer[s:s+3])
>> Value = (Value1*65536)+(Value2*256)+Value3
>> if Value >= 0x800000:
>> Value -= 0x1000000
>> print Value
>> 
>> For example:
>> 16682720 = -94496
>> 
>> Should it be Value -= 0x1000001 so that I get -94497, instead?
> 
> Your first case is correct, "Value -= 0x1000000".  The value 0xFFFFFFF
> should be -1 and 0xFFFFFFF - 0x1000000 == -1.
> 
> An alternative way of doing this:
> 
> 	Value = unpack(">l", Buffer[s:s+3] + "\0")[0] >> 8
> 
> 					Ross Ridge

Good to know (never was good on the math front).

However, in playing around with your suggestion and Grant's code I've 
found that the struct stuff is WAY slower than doing something like this

 Value = (ord(Buf[s])*65536)+(ord(Buf[s+1])*256)+ord(Buf[s+2])
 if Value >= 0x800000:
     Value -= 0x1000000

This is almost twice as fast just sitting here grinding through a few 
hundred thousand conversions (like 3sec vs. ~5secs just counting on my 
fingers - on an old Sun...it's a bit slow).  Replacing *65536 with <<16 
and *256 with <<8 might even be a little faster, but it's too close to 
call without really profiling it.

I wasn't planning on making this discovery today! :)

Bob





More information about the Python-list mailing list