1

Just started learning java and I can't understand what's wrong with my code. PrimeIterator is supposed to generate infinite amount of prime numbers (starting from a number 3) but when I print the output I get: 3, 5, 7, 9, 11, 13, 15 etc.

public class Prime {

    PrimeIterator iter = new PrimeIterator();

    private class PrimeIterator implements java.util.Iterator<Integer>
    {
        int numb = 1;

        public boolean hasNext() 
        {
            return true;
        }

        public Integer next() 
        {
            nextCandidate:
            do{
                numb += 2;
                int numbSqrt = (int)java.lang.Math.sqrt(numb);

                for (int i = 3; i <= numbSqrt; i = i+2)
                {
                    if (numb % i == 0)
                    {
                        continue nextCandidate;
                    }
                }
            }while(false);
            return numb;
        }

        public void remove() {}
    }

    void printPrimes()
    {
        System.out.print(2);
        while(iter.hasNext())
        {
            try 
            {
                Thread.sleep(500);
            } catch (InterruptedException e) 
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }

            System.out.print(", " + iter.next());   
        }
    }
}

I wanted to use labelled "continue" statement for my do-while loop. However my intuition tells me that I use it incorrectly.

dcastro
  • 66,540
  • 21
  • 145
  • 155
matt-pielat
  • 1,659
  • 3
  • 20
  • 33

2 Answers2

1

The trouble is with the while(false) continuation condition. Being a do while(false) statement, this means that it can never loop more than once. That is, when you try to jump the execution to the labeled statement, it won't cycle again through the do while because the continuation condition (false) is not validated, even if you think that continue will make the execution loop again.

So it will never increment numb more than once per next() method execution.

I'd do something like the following:

nextCandidate:
do{
    numb += 2;
    int numbSqrt = (int)java.lang.Math.sqrt(numb);

    for (int i = 3; i <= numbSqrt; i = i+2)
    {
        if (numb % i == 0)
        {
            continue nextCandidate;
        }
    }
    break;

}while(true);
Andrei Nicusan
  • 4,555
  • 1
  • 23
  • 36
1

Here are the problems that I see

  1. You're not even printing output.

  2. (int)java.lang.Math.sqrt(5) will end up truncating to 2. You should add 1 to your square root, since it's a problem if you don't iterate enough, but it's not a problem if you iterate more than you need to.

  3. when you do find a prime number, your for loop will end, and while(false) will terminate the do-while loop

  • @AndreiNicusan you're right. I was afraid that if `i` was 4, than it would say that 4 was prime, but then again, `i` will never be `4` – Sam I am says Reinstate Monica Feb 21 '14 at 16:46
  • I wanted to increase my numbers by 2 to kinda optimize the whole thing. I couldn't nicely implement generating number 2 in my PrimeIterator subclass. – matt-pielat Feb 21 '14 at 16:46
  • actually, not what I think about it more, the square root thing won't actually end up being a problem either – Sam I am says Reinstate Monica Feb 21 '14 at 16:49
  • @Sam, I think you may have produced a full trifecta of wrongness. He produces output through an iterator that can be printed or otherwise used by the caller (a more flexible approach than directly printing). The sqrt truncation is a feature, not a bug. Your third point describes the desired behavior rather than a problem. – phatfingers Feb 21 '14 at 17:05