unsigned 32 bit arithmetic type?
Robin Becker
robin at reportlab.com
Wed Oct 25 19:33:20 CEST 2006
Martin v. Löwis wrote:
> Robin Becker schrieb:
>> def add32(x, y):
>> "Calculate (x + y) modulo 2**32"
>> return ((x&0xFFFFFFFFL)+(y&0xFFFFFFFFL)) & 0xffffffffL
>
> That's redundant; it is sufficient to write
>
> return (x+y) & 0xffffffff
>
>> def calcChecksum(data):
>> """Calculates TTF-style checksums"""
>> if len(data)&3: data = data + (4-(len(data)&3))*"\0"
>> sum = 0
>> for n in unpack(">%dl" % (len(data)>>2), data):
>> sum = add32(sum,n)
>> return sum
>
> That's also redundant; I'd write
>
> def calcChecksum(data):
> data += "\0\0\0\0"[:len(data)&3]
> return sum(unpack(">%dl" % (len(data)>>2), data)) & 0xffffffff
>
> I.e. it is sufficient to truncate to 32 bits at the end, instead of
> doing so after each addition.
I can see the advantage in the summation case where all the numbers are known
positive, however the full problem includes cases where there's an "adjustment"
to the sum and that usually ends up like this
adjustment = unpack('>l', table[8:8+4])[0]
checksum = add32(checksum, -adjustment)
so in those cases I just assumed I needed to force the result into the right
form before doing the addition. Clearly we can only overflow the 31 bits just
once, but don't negative numbers have a potentially infinite number of ones at
the top?
>>> hex(0xFFFFFFFFL-1)
'0xFFFFFFFEL'
>>> hex(0xFFFFFFFFL + (-1&0xFFFFFFFFL))
'0x1FFFFFFFEL'
so I think maybe I need to fix at least some of the numbers going into the add32
function.
--
Robin Becker
More information about the Python-list
mailing list