while loop confusion

my code below gets perfect numbers by doing this:

1+2 = 3(prime)3*2 = 6(perfect)

1+2+4 = 7(prime) 7*4 = 28(perfect)

1+2+4+8+16 = 31(prime)31*16 = 496(perfect).

but i don't understand why it only prints out the first three perfect numbers, and not also the fourth, which is 8128.

my while loop is while(sum < 32){

to print out 496, it calclates 31(sum) * 16(num).

so if sum = 31, sum is therefore below 32, so why does the while loop not do another round and print the fourth perfect number? please help.

class PerfectNumbersThree{

publicstaticvoid main(String[] args){

System.out.print("The first four perfect numbers are: ");

testIfPerfect(0);

}

staticvoid testIfPerfect(int num){

int sum = 0, numMultByTwo = 1;

while(sum < 32){

sum = sum + numMultByTwo;

num = numMultByTwo;

numMultByTwo = num*2;

if(isPrime(sum) ){

int perfectNum = sum*num;

System.out.print(perfectNum+" ");

}

}//close while.

}

staticboolean isPrime(int n){

if(n < 2)returnfalse;

if(n == 2)returntrue;

for (int d = 2; d < n; d+=1)

if (n%d == 0)returnfalse;

returntrue;

}

}

output

The first four perfect numbers are: 6 28 496

[2690 byte] By [mark_8206a] at [2007-11-27 1:06:27]
# 1
while(sum < 64)
prometheuzza at 2007-7-11 23:41:38 > top of Java-index,Java Essentials,New To Java...
# 2
> while(sum < 64)thanks prome, i'll go try to figure out why it's 64!
mark_8206a at 2007-7-11 23:41:38 > top of Java-index,Java Essentials,New To Java...
# 3
> > ...> > thanks prome, i'll go try to figure out why it's 64!Hint:1st = 2 *3 =62nd = 4 *7 =283rd = 16 * 31 = 4964th = 64 * 127 = 8128
prometheuzza at 2007-7-11 23:41:38 > top of Java-index,Java Essentials,New To Java...
# 4
isn't 64 the value of num, and not sum?
mark_8206a at 2007-7-11 23:41:38 > top of Java-index,Java Essentials,New To Java...
# 5

Why not let your end condition (output *4* perfect numbers) be the condition for your while loop?

Something like this:

static void testIfPerfect(int num)

{

int sum = 0, numMultByTwo = 1;

int perfectNumberCount = 0; // a new variable

while (perfectNumberCount < 4) // this seems more logical

{

sum = sum + numMultByTwo;

num = numMultByTwo;

numMultByTwo = num * 2;

if (isPrime(sum))

{

int perfectNum = sum * num;

System.out.print(perfectNum + " ");

perfectNumberCount++; // increment variable when perf numb found

}

} // close while.

}

Also, your testIfPerfect routine is a little deceiving to my eyes. It kind of makes me believe that it takes a parameter and tests it and only it to see if it is a perfect number. In fact what it does is tests all numbers from 0 to whatever. There are two ways to make this clearer:

1) take the variable num and declare it inside the method, and change the method to a parameter-less form: static void testForPerfectNumbers() {....

or

2) change it to a true function that tests for perfect numbers: static boolean testIfPerfect(int num) {....

then loop through your numbers in a higher level routine such as the main routine.

petes1234a at 2007-7-11 23:41:38 > top of Java-index,Java Essentials,New To Java...
# 6
thanks petes, but i still don't follow the while loop in my code, when 496 gets printed,(31*16) the value of sum is 31, is that correct?
mark_8206a at 2007-7-11 23:41:38 > top of Java-index,Java Essentials,New To Java...
# 7

> thanks petes, but i still don't follow the while loop

> in my code,

> when 496 gets printed,(31*16) the value of sum is 31,

> is that correct?

I find that in this situation when I want to know what variables are doing at a certain time is either to sprinkle a few "System.out.println(myVariable);" in my code, or step through it with a debugger. Why not put a few S.o.println()s in the if (isPrime(sum)) block? Let your program do the hard work and tell you what you need to know.

petes1234a at 2007-7-11 23:41:38 > top of Java-index,Java Essentials,New To Java...
# 8

> > thanks petes, but i still don't follow the while

> loop

> > in my code,

> > when 496 gets printed,(31*16) the value of sum is 31,

> > is that correct?

>

> I find that in this situation when I want to know

> what variables are doing at a certain time is either

> to sprinkle a few "System.out.println(myVariable);"

> in my code, or step through it with a debugger. Why

> not put a few S.o.println()s in the if

> (isPrime(sum)) block? Let your program do the hard

> work and tell you what you need to know.

; )

petes1234, that's exactly what has been proposed to Mark in about every thread he started!

@Mark, you seem to be smart guy (from what I've seen so far), but why don't you try to answer those questions yourself by debugging your code? (no offense meant!)

prometheuzza at 2007-7-11 23:41:38 > top of Java-index,Java Essentials,New To Java...
# 9

>why don't you try to answer those

> questions yourself by debugging your code? (no

> offense meant!)

i changed my code slightly so i could see the value of the sum variable at the end of the while loop.

i can see the value of sum is 31 by

int perfectNum = sum*num;

System.out.print(sum+" multiplied by "+num+" is ");

System.out.println(perfectNum);

this prints: 31 multiplied by 16 is 496

so sum is 31, num is 16, and perfectNum is 496.

and that's what i don't understand, if the value of sum is below 32 then the while loop should keep on going, but somehow it stops and doesn't print the fourth number.

class PerfectNumbersTest {

public static void main(String[] args) {

System.out.println("The first four perfect numbers: ");

testIfPerfect(0);

}

static void testIfPerfect(int num) {

int sum = 0, numMultByTwo = 1;

while(sum < 32) {

sum = sum + numMultByTwo;

num = numMultByTwo;

numMultByTwo = num*2;

if(isPrime(sum) ) {

int perfectNum = sum*num;

System.out.print(sum+" multiplied by "+num+" is ");

System.out.println(perfectNum);

}

} //close while.

}

static boolean isPrime(int n) {

if(n < 2) return false;

if(n == 2) return true;

for (int d = 2; d < n; d+=1)

if (n%d == 0) return false;

return true;

}

}

The first four perfect numbers:

3 multiplied by 2 is 6

7 multiplied by 4 is 28

31 multiplied by 16 is 496

mark_8206a at 2007-7-11 23:41:38 > top of Java-index,Java Essentials,New To Java...
# 10

I don't understand what there's not to understand actually. Run this code:

class PerfectNumbersThree {

public static void main(String[] args) {

testIfPerfect(0);

}

static void testIfPerfect(int num) {

int sum = 0, numMultByTwo = 1;

while(sum < 32) {

sum = sum + numMultByTwo;

num = numMultByTwo;

numMultByTwo = num*2;

if(isPrime(sum)) {

int perfectNum = sum*num;

System.out.println("Perfect number = sum * num = "+

sum+" * "+num+" = "+perfectNum);

}

System.out.println("sum = "+sum);

if(sum >= 32) {

System.out.println("sum >= 32, stop looping!");

}

}

}

static boolean isPrime(int n) {

if(n < 2) return false;

if(n == 2) return true;

for (int d = 2; d < n; d+=1)

if (n%d == 0) return false;

return true;

}

}

Whenever sum is more than 31, the while loop terminates. Since 8128 = 127*64, the 4th perfect number is naturally not printed since 127 (or 64, which ever is your sum variable) is more than 31.

prometheuzza at 2007-7-11 23:41:38 > top of Java-index,Java Essentials,New To Java...