2's complement conversion. Is this right?

Grant Edwards grante at visi.com
Fri Apr 18 16:17:35 EDT 2008


On 2008-04-18, 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?

Nope. -94496 is the right answer:

>>> -94496 & 0xffffff
16682720

Here's another way to do it:

------------------------------------------------------------------
import struct

def tohex(s):
    return '0x' + ''.join(['%0.2x' % ord(b) for b in s])

def from3Bytes(s):
    # sign extend the three byte number in s to make it 4 bytes long
    if ord(s[0]) & 0x80:
        s = '\xff'+s
    else:
        s = '\x00'+s
    return struct.unpack('>i',s)[0]

for v in 0,1,-2,500,-500,7777,-7777,-94496,98765,-98765,8388607,-8388607,-8388608:
    s = struct.pack('>i',v)[1:]
    print "%8d %s %8d" % (v, tohex(s), from3Bytes(s))
------------------------------------------------------------------


-- 
Grant Edwards                   grante             Yow! I'll eat ANYTHING
                                  at               that's BRIGHT BLUE!!
                               visi.com            



More information about the Python-list mailing list