2016-08-12 2 views
-1

Есть ли способ в BigInteger получить значение дополнения 2? Для, например: если есть BigInteger с отрицательным значениемКак получить значение дополнения 2 в BigInteger произвольной длины

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

, то я хочу, чтобы получить 2 в дополнение в виде BigInteger

BigInteger b = E8C4713AFBB863C16A214FB9FBEE69D0610D131F2C55328B641D61EFF9037848 

я могу вычитать первый BigInteger из 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF, чтобы получить второй BigInteger, но есть ли общий метод для вычисления этого для BigInteger любой длины?

+1

Извините, у меня нет ответа, но для чего именно вы это используете? – Michael

+0

Мы следим за протоколом на Android и iOS. В iOS BIGNUM получает + ve, но в Android BigInteger показывает номер -ve (дополнение 2). Нам нужно сопоставить оба значения для наших вычислений. – Harish

+0

И почему вы используете BigInteger для этого? Я предполагаю, что это больше проблема парсера протокола. Я рекомендую вам отредактировать свой вопрос и добавить информацию и код о том, какие данные вы получите, и как вы его разбираете, и что вы делаете после этого. – Robert

ответ

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 действительно дополняют до двух , а не только повторная интерпретация бит.

+0

Если вы не хотите изменять положительные BigIntegers, то либо не вызывайте 'twosComplement()', если BigInteger уже положителен, либо пусть он возвращается, когда 'original' положителен. Вышеуказанное преобразует -ve в + ve и наоборот. –

+0

Спасибо, Руди, я включил условие ниже для -ve BigIntegers, и он работает нормально. if (b.compareTo (BigInteger.ZERO) <0) { b = twosComplement (b); } – Harish

+0

@Harish: YAY!

Смежные вопросы