Como usar o BigInteger?

153

Eu tenho este pedaço de código, que não está funcionando:

BigInteger sum = BigInteger.valueOf(0);
for(int i = 2; i < 5000; i++) {
    if (isPrim(i)) {
        sum.add(BigInteger.valueOf(i));
    }
}

A variável sum é sempre 0. O que estou fazendo de errado?

cc.
fonte
A propósito, a soma deve caber facilmente int, portanto você não precisa BigIntegerdeste exemplo.
Notnoop 23/11/2009
8
Não, eu mudei o código. O número é maior que 5000.
cc.
A questão ligada como duplicado não parecem ter o mesmo problema que esta questão (a questão ligada é sobre qual função para uso, de modo BigInteger pode ser adicionado, este é sobre como usar a função add)
justhalf

Respostas:

203

BigIntegeré imutável. O javadocs afirma que add () "[r] retorna um BigInteger cujo valor é (this + val)." Portanto, você não pode alterar sum, é necessário reatribuir o resultado do addmétodo para sumvariável.

sum = sum.add(BigInteger.valueOf(i));
MarkPowell
fonte
1
int será suficiente contanto que você não ultrapasse 2 ^ 31-1, tempo será suficiente contanto que você não ultrapasse 2 ^ 63-1.
31711 Jean Hominal
2
O que, em seu exemplo, ele não vai.
MarkPowell 23/11/2009
105
Mas é realmente difícil pensar que talvez ele tenha simplificado seu exemplo até exatamente qual é o problema?
Thecoshman
@ thecoshman - Você está certo e o número de votos no seu comentário mostra que esse é um conselho sábio para todos os leitores dessas perguntas. Um conselho mais sábio é " leia o que os outros escreveram antes de responder ou comentar " . Por exemplo, neste caso, nem sequer requer QUALQUER pensamento, pois o OP afirmou claramente que ele fez exatamente isso nos comentários abaixo da pergunta: " Não, eu mudou o código. O número é maior que 5000. "
OMY 08/04
58
sum = sum.add(BigInteger.valueOf(i))

A BigIntegerclasse é imutável, portanto você não pode mudar seu estado. Assim, chamar "add" cria um novo BigInteger, em vez de modificar o atual.

Bozho
fonte
22

Outras respostas acertaram em cheio; BigInteger é imutável. Aqui está a pequena alteração para fazer esse código funcionar.

BigInteger sum = BigInteger.valueOf(0);
for(int i = 2; i < 5000; i++) {
    if (isPrim(i)) {
        sum = sum.add(BigInteger.valueOf(i));
    }
}
Dean J
fonte
11

BigInteger é uma classe imutável. Portanto, sempre que você fizer qualquer aritmética, é necessário reatribuir a saída a uma variável.

Poindexter
fonte
11

java.math.BigIntegeré uma classe imutável, portanto não podemos atribuir novo objeto no local do objeto já atribuído. Mas você pode criar um novo objeto para atribuir um novo valor, como:

sum = sum.add(BigInteger.valueOf(i));
Arvind
fonte
3

Sim, é imutável

sum.add(BigInteger.valueOf(i));

portanto, o método add () da classe BigInteger não adiciona o novo valor BigIntger ao seu próprio valor, mas cria e retorna uma nova referência BigInteger sem alterar o BigInteger atual e é isso que foi feito mesmo no caso de Strings

murali krish
fonte
0

Na verdade você pode usar,

BigInteger sum= new BigInteger("12345");

Para criar um objeto para a classe BigInteger.Mas o problema aqui é que você não pode fornecer uma variável entre aspas duplas.Por isso, precisamos usar o método valueOf () e armazenar a resposta nessa soma novamente.

sum= sum.add(BigInteger.valueOf(i));
atormentar
fonte
0

Bigintegeré uma classe imutável. Você precisa atribuir explicitamente o valor da sua saída para somar assim:

sum = sum.add(BigInteger.valueof(i));    
Arpna Joshi
fonte
4
Agora essa é a 8ª resposta com a mesma explicação, então como é que essa resposta é útil?
Tom
-6

Como você está resumindo alguns valores int juntos, não há necessidade de usar o BigInteger. longé o suficiente para isso. inté de 32 bits, enquanto longé de 64 bits, que pode conter a soma de todos os valores int.

frank.liu
fonte
"Mas é realmente difícil pensar que talvez ele tenha simplificado seu exemplo até exatamente qual é o problema?" (citando thecoshman)
Bulwersator
5
Para esta pergunta, minha resposta é um pouco do nosso escopo. Desde o tópico, concentre-se em como usar o BigInteger. Apenas uma das minhas experiências pessoais, se quisermos resumir alguns números inteiros e os números não forem muito grandes, eu preferiria por muito tempo. Porque é fácil de usar e roda mais rápido. Para entrada em larga escala, o BigInteger é a boa escolha.
frank.liu