Преобразование очень большого целого числа в битовый вектор завершается неудачно
import java.math.BigInteger;
import java.util.ArrayList;
public class Factorial {
public static int[] bitVector(int n) {
ArrayList<Integer> bitList = new ArrayList<Integer>();
BigInteger input = computeFactorial(n);
System.out.println(input);
BigInteger[] result = input.divideAndRemainder(new BigInteger(String.valueOf(2)));
if (result[0].intValue()==0) {return new int[]{result[1].intValue()};}
else {
bitList.add(result[1].intValue());
}
while(result[0].intValue() != 0) {
result = result[0].divideAndRemainder(new BigInteger(String.valueOf(2)));
bitList.add(result[1].intValue());
}
int[] array = new int[bitList.size()];
for (int i=0; i<array.length; i++) {
array[i]=bitList.get(i).intValue();
}
return array;
}
public static BigInteger computeFactorial(int n) {
if (n==0) {
return new BigInteger(String.valueOf(1));
} else {
return new BigInteger(String.valueOf(n)).multiply(computeFactorial(n-1));
}
}
public static void main(String[] args) {
int[] bitVector = bitVector(35);
for (int bit: bitVector)
System.out.print(bit+" ");
System.out.println();
}
}
Код выше работает нормально, когда вход bitVector
не больше чем 35
, Тем не менее, когда я прохожу 36
в качестве параметра для bitVector
все, кроме одного бита, ушли в вывод.
Я потенциально исключил следующие причины:
Это может не иметь ничего общего с типом BigInteger, так как он был спроектирован так, чтобы никогда не переполняться.
Это не может быть связано с использованием памяти программой, которая использует только
380M
во время выполнения.Я распечатываю значение
computeFactorial(36)
, который выглядит хорошо.
Что на земле происходит там?
2 ответа
Итак, что вы пытаетесь сделать, это
public static String factorialAsBinary(int n) {
BigInteger bi = BigInteger.ONE;
for (; n > 1; n--)
bi = bi.multiply(BigInteger.valueOf(n));
return bi.toString(2);
}
public static void main(String... args) {
String fact36 = factorialAsBinary(36);
for (char ch : fact36.toCharArray())
System.out.print(ch + " ");
System.out.println();
}
который печатает
1 0 0 0 1 0 0 0 1 0 1 0 0 1 1 0 0 0 0 1 0 1 0 1 1 0 0 1 0 1 1 0 1 1 1 1 0 1 1 1 0 1 0 1 0 0 0 0 0 1 1 1 0 1 0 0 0 0 1 0 0 0 1 0 0 0 1 0 0 1 0 1 0 0 0 0 1 1 1 1 1 0 0 1 1 1 1 0 0 1 1 1 0 1 1 0 0 1 1 1 1 1 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
Что на земле происходит там?
Ваш код намного сложнее, чем должен быть, что также облегчает ошибки и затрудняет понимание.
result[0].intValue()
неправильно:
intValue ():
Преобразует этот BigInteger в Int. Это преобразование аналогично сужающему примитивному преобразованию из long в int, как определено в Спецификации языка Java: если этот BigInteger слишком велик, чтобы поместиться в int, возвращаются только младшие 32 бита. Обратите внимание, что это преобразование может потерять информацию об общей величине значения BigInteger, а также вернуть результат с обратным знаком.
в вашем случае он возвращает младшие 32 бита, которые равны нулю, поэтому вы возвращаете 0 после первого деления