BigInteger中是否有方法可以获得2的补码值? 例如:如果有一个负值的BigInteger
BigInteger a = new BigInteger("-173B8EC504479C3E95DEB0460411962F9EF2ECE0D3AACD749BE39E1006FC87B8", 16);
然后我想以BigInteger形式获得2的补码
BigInteger b = E8C4713AFBB863C16A214FB9FBEE69D0610D131F2C55328B641D61EFF9037848
我可以从0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF中减去第一个BigInteger来获取第二个BigInteger但是有一个通用方法可以为任意长度的BigInteger计算这个吗?
答案 0 :(得分:2)
要使这个值成为它的两个补码,你将不得不操纵内容。这当然是不可能的,所以你先把内容拿出来,操纵它们然后把它们变成新的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");
}
输出:
-173B8EC504479C3E95DEB0460411962F9EF2ECE0D3AACD749BE39E1006FC87B8
E8C4713AFBB863C16A214FB9FBEE69D0610D131F2C55328B641C61EFF9037848
E8C4713AFBB863C16A214FB9FBEE69D0610D131F2C55328B641D61EFF9037848
这个新的BigInteger
实际上是两个补码,而不仅仅是对比特的重新解释。