На самом деле преобразование довольно простое.Вы можете использовать маскирование, аналогичное преобразованию целых чисел без знака в long:
Давайте сначала создадим маску как постоянную (это просто приводит к тому, что для младших 32 битов установлено значение 1):
private static final long UNSIGNED_INT_MASK = (1L << Integer.SIZE) - 1L;
тогда мы можем выполнить:
int unsignedInt = 0x8000_0000; // sample input value
long l = (long) unsignedInt & UNSIGNED_INT_MASK;
Таким образом, для BigInteger
мы можем создать такую маску (64 младших разряда установлены в 1):
// use "import static java.math.BigInteger.ONE;" to shorten this line
private static final BigInteger UNSIGNED_LONG_MASK = BigInteger.ONE.shiftLeft(Long.SIZE).subtract(BigInteger.ONE);
отлично, тогда все остальное будет легко:
long unsignedLong = 0x8000_0000_0000_0000L; // sample input value
BigInteger bi = BigInteger.valueOf(unsignedLong).and(UNSIGNED_LONG_MASK);
Это не ракетостроение, но иногда вы просто хотите найти быстрый и легкий ответ.