Ваш код C полагается на биты, сдвигаемые от старшего конца unsigned long long
. (Они поворачиваются на другой конец другим сдвигом.) BigInteger имеет произвольную точность и, следовательно, не имеет конца, поэтому сдвинутые влево биты никогда не сдвигаются.
Вы можете создать 64-битную BigInteger поразрядную маску AND и AND после сдвига влево. Это интуитивное решение.
Вы также можете просто игнорировать старшие байты.
byte[] bar = foo.toByteArray();
if (bar.length > 8) {
bar = System.arrayCopy(bar, bar.length - 8, new byte[8], 0, 8);
}
Если len
большое, то это простое решение будет растрачивать память.
В любом случае есть более разумное и более эффективное решение. Все целочисленные типы Java со знаком гарантированно будут иметь семантику дополнения до двух. Битовая семантика для арифметики с двумя целыми числами дополнения и целыми числами без знака идентична - разница только в интерпретации значения! Так что просто используйте исходный код C (подстановка в Java long
) и в конце интерпретируйте их по-своему .
byte[] longToByteArray(long x) {
byte[] array = new byte[8];
for (int i = 7; i >= 0; i--) {
array[i] = (byte)x;
x >>>= 8;
}
}
Кстати, обязательно замените оператор >>
в коде C на оператор Java >>>
.