Two's Complement in Python Two's Complement in Python python python

Two's Complement in Python


Two's complement subtracts off (1<<bits) if the highest bit is 1. Taking 8 bits for example, this gives a range of 127 to -128.

A function for two's complement of an int...

def twos_comp(val, bits):    """compute the 2's complement of int value val"""    if (val & (1 << (bits - 1))) != 0: # if sign bit is set e.g., 8bit: 128-255        val = val - (1 << bits)        # compute negative value    return val                         # return positive value as is

Going from a binary string is particularly easy...

binary_string = '1111' # or whatever... no '0b' prefixout = twos_comp(int(binary_string,2), len(binary_string))

A bit more useful to me is going from hex values (32 bits in this example)...

hex_string = '0xFFFFFFFF' # or whatever... '0x' prefix doesn't matterout = twos_comp(int(hex_string,16), 32)


It's not built in, but if you want unusual length numbers then you could use the bitstring module.

>>> from bitstring import Bits>>> a = Bits(bin='111111111111')>>> a.int-1

The same object can equivalently be created in several ways, including

>>> b = Bits(int=-1, length=12)

It just behaves like a string of bits of arbitrary length, and uses properties to get different interpretations:

>>> print a.int, a.uint, a.bin, a.hex, a.oct-1 4095 111111111111 fff 7777


Since Python 3.2, there are built-in functions for byte manipulation: https://docs.python.org/3.4/library/stdtypes.html#int.to_bytes.

By combining to_bytes and from_bytes, you get

def twos(val_str, bytes):    import sys    val = int(val_str, 2)    b = val.to_bytes(bytes, byteorder=sys.byteorder, signed=False)                                                              return int.from_bytes(b, byteorder=sys.byteorder, signed=True)

Check:

twos('11111111', 1)  # gives -1twos('01111111', 1)  # gives 127

For older versions of Python, travc's answer is good but it does not work for negative values if one would like to work with integers instead of strings. A twos' complement function for which f(f(val)) == val is true for each val is:

def twos_complement(val, nbits):    """Compute the 2's complement of int value val"""    if val < 0:        val = (1 << nbits) + val    else:        if (val & (1 << (nbits - 1))) != 0:            # If sign bit is set.            # compute negative value.            val = val - (1 << nbits)    return val