问题
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?
回答1:
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);
System.out.println(a.toString(16).toUpperCase());
System.out.println(b.toString(16).toUpperCase());
// for comparison, from question:
System.out.println("E8C4713AFBB863C16A214FB9FBEE69D0610D131F2C55328B641D61EFF9037848");
}
Output:
-173B8EC504479C3E95DEB0460411962F9EF2ECE0D3AACD749BE39E1006FC87B8
E8C4713AFBB863C16A214FB9FBEE69D0610D131F2C55328B641C61EFF9037848
E8C4713AFBB863C16A214FB9FBEE69D0610D131F2C55328B641D61EFF9037848
And this new BigInteger
is really the two's complement, not just a re-interpretation of the bits.
来源:https://stackoverflow.com/questions/38918190/how-to-get-the-2s-complement-value-of-a-biginteger-of-arbitrary-length