Numeros Primos

9 respostas
B

Gente, estou tentando criar um método que retorne true caso o número for primo e false caso seja falso. Segue o método:

private static int i = 2;
	
	public static boolean primo(int num){
	
		boolean resultado = true;
		
		while(i < num){
			
			
			if(num % i == 0){
				resultado = false;
                             break;
			}
			
			++i;
		}
		
	return resultado;
}

Se usar esse método inserindo o parametro manualmente, dá certo. Mas quando eu coloco dentro de um loop pra retornar todos os primos de 1 até 1000, ele retorna todos os números como true. Exemplo:

for(int a = 2; a < 1000; a++)
{        
    System.out.println(a + "-" +  Classe.primo(a));    
}

‘-’ Alguém sabe o motivo? Já quebrei a cabeça aqui e nada.

@edit

Editei pra formular melhor a perguntar, e inseri o break; no if.

@edit2

Troquei o while por um for e deu certo. Mas alguém sabe me explicaro porque estava acontecendo isso? kkk

Segue como ficou o método da maneira certa:

public static boolean primo(int num){
    
        boolean resultado = true;
        
        for(int i = 2; i < num ; ++i){
            
            
            if(num % i == 0){
                resultado = false;
            }
            
        }
        
    return resultado;
}

9 Respostas

D

Observei umas coisas, vamos ver se concorda comigo.

No primeiro método, veja que você já definiu o resultado como true. Ao receber o a = 2 lá do laço for o método primo() já vai direto pro return resultado = true, pois o while não rodou porque o 2 é igual ao num e não menor.

para os demais, seu if não vai retornar o true, pois quando seu i for igual ao num ele vai sair do while. sacou?

veja a saída abaixo. copiei seu código e acrescentei um "System.out.println(“valor de i no while: " + i);” após seu ++i.
2-true
valor de i no while: 3
3-true
valor de i no while: 4
4-true
valor de i no while: 5
5-true
valor de i no while: 6
6-true
valor de i no while: 7
7-true
valor de i no while: 8
8-true
valor de i no while: 9
9-true

viu como no 2 ele sequer entrou no while?

Já no for alterado, ele vai executar como planejado pois vai verificar o if em todo o loop.

D

Pensei melhor aqui. Agora seu while vai funcionar. Tem que ser assim:

public static boolean primo(int num){

boolean resultado = true;
	int i = 2;
	
	while (i < num){
		
		if (num % i == 0){
			resultado = false;
            break;
		}
		
		++i;
	}
	
return resultado;
}

veja na saída que postei anteriormente. Eu não tinha prestado atenção. acontece que mandei imprimir i a cada loop do while mas pode ver que só passou 1x dentro dele pra cada número passado. O i tem que estar dentro do método e não static na classe. como a variável estática recebia o ++i, seu método só rodava 1x, pois para cada novo argumento ‘a’ passado ele já estava com de ‘a-1’, passava pelo loop uma vez e saia adicionando mais uma vez o ‘i’ e assim sucessivamente.

aqui deu certo:
2-true
3-true
4-false
5-true
6-false
7-true
8-false
9-false
10-false
11-true
12-false
13-true
14-false
15-false
16-false
17-true

me corrijam se falei alguma besteira. sou novato. rsrsrs!

M

Olá.

Dei uma olhada aqui e problema está com a variável i que você usa dentro do método primo(int num).

O problema é que a cada passada do for a variável i tem que ser atualizada para 2.
Faça a seguinte alteração.

public static boolean primo(int num){
	int i = 2;// <--------- Coloque a variável i dentro do método.
	boolean resultado = true;

	while(i < num){

		if(num % i == 0){
			resultado = false;
			break;
		}
		++i;
	}

	return resultado;
}

Assim fazendo a impressão chamando o método retornará os resultados corretos.

for(int a = 2; a < 1000; a++)
{        
    System.out.println(a + "-" +  Classe.primo(a));    
}

Testa ai e veja se dá certo.
Abraço

B

Deu certo sim colocando a variavel dentro do método. Mas não gostei muito disso…
Pois, caso eu quisesse acessar a variavel de fora da classe, não daria certo.
Por exemplo, eu quisesse saber todos os números primos de um loop a partir do número 100, eu só precisava alterar a váriavel i e funcionária. (é só um exemplo que eu nunca vou usar, mass… kkk)
Quando eu chegar em casa vou criar a variavel fora do método for e vou iniciar ela dentro dele. Pra ver se dá certo.

T

Jovem, vi todas as resposta, seu pecado foi tentar usar um método de outra classe, método esse que dependia de uma variável definida como private, sendo assim seu loop não funcionou muito bem quando tentou acessa-la através de outra classe, diferente do primeiro caso, quando acessou diretamente por ela (assim o private não interferiu). Sendo assim acredito que uma solução seria definir como “public static int i = 2;” ao inves de private, podendo assim acessar a classe que depende dessa variável sem nenhum problema. Tente essa solução, não sei se faz sentido também, mas aguardo uma resposta.

B

Thi_Ego, o método funciona normal fora da classe, contanto que esteja fora de um loop.
Mas de qualquer forma irei testar quando chegar em casa.

D

@Thi_Ego, creio que mesmo tornando público não irá funcionar. Veja que mesmo ela sendo private ela pertence à própria classe onde está o método. Logo, não tem problema ser private (na verdade é até melhor que assim seja).

O problema é que por ser static ela recebe um valor único que vale em qualquer parte da classe. Ou ele redefine o valor para 2 assim que iniciar o método, como o @magalhas falou, ou ele torna ela uma variável interna ao método.

BlackHeartH, mas você pode iniciar do 100, já que o número inicial a ser verificado não é o i e sim o a passado no for. Concorda?

independente do número inicial a ser verificado (e você pode criar um scan pra obter esse parâmetro direto da console, bem como o num max também) o i tem que começar do 2. Acho que a solução mais bacana é iniciar o i diretamente no método, pois isso será constante. Se deixar fora e como static e não redefinir seu valor a cada entrada no método, então seu método usará o valor previamente definido e dará errado.

L

Galera,

Dada a quantidade de respostas desencontradas, vou explicar o que acontece com o código.

Quando você define um objeto global como

private static int i = 2;

Você está dizendo a classe que esse objeto é do tipo estático, ou seja, ele não se altera. Isso significa que quando você chama o Classe.primo(a), ele irá instanciar uma única vez objeto estático i = 2. No entanto, quando acessa o método e encontrar um ++i (que poderia ser um i++, não fazendo diferença nenhuma nesse contexto), ele troca o i = 3 e assim permanece. Ou seja, cada vez que você chama o Classe.primo(a), ele vai direcionar para o espaço em memória referenciar o espaço em memória destinado ao mesmo objeto estático da primeira vez.

De forma mais descritiva, o que acontece é que, quando você chama Classe.primo(2), pelo fato do i e o num serem iguais, ele não entra no while, retornando true. Ao chamar Classe.primo(3), ele entra no while, troca o i = 3 e retorna true. Ao chamar Classe.primo(4), como i = 3, ele vai entrar no while, trocar para i = 4 e retornar true. Ou seja, você está testando se o elemento anterior ao num divide ele. Pelo fato de serem primos entre si, sempre vai retornar true.

O maior problema em questão é que você está definindo objetos e métodos estáticos em uma classe que sequer pertence a sua classe principal (onde está o main), nem que lidam com objetos estáticos de fato. O correto, portanto, seria

class Classe

public class Classe{

private int i = 2;

public boolean primo(int num) {

i = 2;

boolean resultado = true;

while (i < num) {

if (num % i == 0) {

resultado = false;

break;

}

++i;

}

return resultado;

}

}

e

Classe classe = new Classe();
for(int a = 2; a < 1000; a++){        
 	System.out.println(a + "-" +  classe.primo(a));    
 }

Dessa forma, você pode está utilizando um objeto não estático de verdade :slight_smile:

Apenas para curiosidade: para poupar processamento, o while pode ser feito até a raiz quadrada do num. Caso um divisor não seja encontrado antes da raiz, não vai existir outro posterior a raiz.

while (i <= Math.sqrt(num)) {

Por exemplo, 12 = 2 x 6. 2 é anterior à raiz e 6 é posterior à raiz. No melhor dos casos, você pode ter a própria raiz, como 9 = 3 x 3.

B

Uma explicação bem mais clara, obrigado @Logusmao

Quanto a raiz quadrada, estava no próximo exercício explicando isso. kkkk

Criado 27 de junho de 2016
Ultima resposta 29 de jun. de 2016
Respostas 9
Participantes 5