Harish Harish - 1 year ago 53
Android Question

How to get the 2's complement value of a BigInteger of arbitrary length

Is there a method in BigInteger to get the 2's complement value?
For eg: if there is a BigInteger with a negative value

BigInteger a = new BigInteger("-173B8EC504479C3E95DEB0460411962F9EF2ECE0D3AACD749BE39E1006FC87B8", 16);

then I want to get the 2's complement in a BigInteger form

BigInteger b = E8C4713AFBB863C16A214FB9FBEE69D0610D131F2C55328B641D61EFF9037848

I can subtract the first BigInteger from 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF to get the second BigInteger but is there a generic method to calculate this for a BigInteger of any length?

Answer Source

To make this value its two's complement, you will have to manipulate the contents. That is of course impossible, so you first get the contents out, manipulate them and then get them into a new BigInteger:

public static BigInteger twosComplement(BigInteger original)
    // for negative BigInteger, top byte is negative  
    byte[] contents = original.toByteArray();

    // prepend byte of opposite sign
    byte[] result = new byte[contents.length + 1];
    System.arraycopy(contents, 0, result, 1, contents.length);
    result[0] = (contents[0] < 0) ? 0 : (byte)-1;

    // this will be two's complement
    return new BigInteger(result);

public static void main(String[] args)
    BigInteger a = new BigInteger("-173B8EC504479C3E95DEB0460411962F9EF2ECE0D3AACD749BE39E1006FC87B8", 16);
    BigInteger b = twosComplement(a);


    // for comparison, from question:



And this new BigInteger is really the two's complement, not just a re-interpretation of the bits.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download