Finding perfect numbers 
Author Message
 Finding perfect numbers

I took an examination in my COBOL class earlier this evening and was troubled by
one of the test questions.  I know it's one of those "too easy to be easy" questions.

If it's not out of line, I thought I would post the question and my thoughts on it,
then ask for feedback.

Question (from memory):  A perfect number is a number which is equal to the cube
of its component digits summed -- that is, 153 is a perfect number because it is
equal to 1*1*1 + 5*5*5 + 3*3*3.  Code a COBOL program to find the perfect numbers
between 100 and 999.

I came up with this, but I'm not convinced that this is the right approach -- beyond
the apparent problems with this code itself.

       Data Division.
       Working-Storage Section.
       01  Hundreds                PIC   9 Value Zeros.
       01  Tens                    PIC   9 Value Zeros.
       01  Ones                    PIC   9 Value Zeros.
       01  Test-Case               PIC 999 Value Zeros.
       01  Test-Number             PIC 999 Value Zeros.
       01  Perfect-Number-Counter  PIC  99 Value Zeros.

       Procedure Division.
       Mainline.
           Perform Tester
               Varying Hundreds from 1 by 1 Until Hundreds > 9
                   After Tens from 0 by 1 Until Tens > 9
                       After Ones from 0 by 1 Until Ones > 9.
           Display Perfect-Number-Counter ' perfect numbers found.'.
           Stop Run.

       Tester.
           String  Hundreds delimited by size
                   Tens delimited by size
                   Ones delimited by size
                       Into Test-Number.
           Compute Test-Case = (Hundreds * Hundreds * Hundreds) +
                               (Tens * Tens * Tens) +
                               (Ones * Ones * Ones).
           If Test-Case = Test-Number
               Display Test-Case ' is a perfect number'
               Add 1 to Perfect-Number-Counter.

I don't think I handled the varying clause correctly . . . I need the digits to hit
and include '9' before stopping but what happens when they hit '10' but are only PIC 9s
-- my thinking is that I get a '0' b/c or right-left numeric movement, but more
importantly, this means a loop.  If I use '= 9' then I will stop at 888.  Should I have
made the digits all PIC 99's?  That changes the string . . . This seems to be getting real
big, real quick.  I must be missing something obvious.

How close am I to an (the) answer?  By the way, the test _is_ over :)

John S.



Mon, 05 Oct 1998 03:00:00 GMT  
 Finding perfect numbers
Yikes!  I know it's bad form to be the first to respond to one's own post,
but I have to correct a not-insignificant mistake.

Quote:
> Question (from memory):  A perfect number is a number which is equal to the cube
> of its component digits summed -- that is, 153 is a perfect number because it is
> equal to 1*1*1 + 5*5*5 + 3*3*3.  Code a COBOL program to find the perfect numbers
> between 100 and 999.

Should be:

A perfect number is a number which is equal to the sum of the cubes of its component digits.

JS



Mon, 05 Oct 1998 03:00:00 GMT  
 Finding perfect numbers

Quote:

> I don't think I handled the varying clause correctly . . . I need the
digits to hit
> and include '9' before stopping but what happens when they hit '10' but
are only PIC 9s
> -- my thinking is that I get a '0' b/c or right-left numeric movement,
but more
> importantly, this means a loop.  If I use '= 9' then I will stop at

888.  Should I have

Quote:
> made the digits all PIC 99's?  That changes the string . . . This seems
to be getting real
> big, real quick.  I must be missing something obvious.

Yes indeed - having a single digit for hundreds, tens, and ones will very
likely get you into hot water with the >9 test. My approach would be to
define each of these as PIC 99 and then instead of the STRING...DELIMITED BY
SIZE I would use a reference modified move as in

 MOVE Hundreds (2:1) to Test-Number (1:1)
 MOVE Tens (2:1) to Test-Number (2:1)
 MOVE Ones (2:1) to Test-Number (3:1)

....and methinks you are safe...

--
Jitze Couperus                   |     Tel:(408)541-4334
Conrol Data Systems Inc.         |     Fax:(408)541-4206

        Any opinions expressed are mine alone.          



Mon, 05 Oct 1998 03:00:00 GMT  
 Finding perfect numbers


Quote:
>Question (from memory):  A perfect number is a number which is equal to the cube
>of its component digits summed -- that is, 153 is a perfect number because it is
>equal to 1*1*1 + 5*5*5 + 3*3*3.  Code a COBOL program to find the perfect numbers
>between 100 and 999.

Wouldn't somthing like this be simpler?

       DATA DIVISION.
       WORKING-STORAGE SECTION.
       01  TST-FLD        PIC 9(4).
       01  TST-FLD-REDEF  REDEFINES TST-FLD.
         03  FILLER       PIC 9.
         03  DSP-FLD.
           05  TF-1       PIC 9.
           05  TF-2       PIC 9.
           05  TF-3       PIC 9.

       PROCEDURE DIVISION.
       MAIN-LINE.
           PERFORM VARYING TST-FLD FROM 100 BY 1 UNTIL TST-FLD > 999
             IF TST-FLD = TF-1 ** 3 + TF-2 ** 3 + TF-3 ** 3
               DISPLAY DSP-FLD " is a perfect number".
           STOP RUN.

I wrote this using MF COBOL, and it seemed to work.  It certainly uses
less working-storage and procedure code.  Probably runs quicker too.

Ken Row



Mon, 05 Oct 1998 03:00:00 GMT  
 Finding perfect numbers

Quote:

>I took an examination in my COBOL class earlier this evening and was troubled by
>one of the test questions.  I know it's one of those "too easy to be easy" questions.
>If it's not out of line, I thought I would post the question and my thoughts on it,
>then ask for feedback.
>Question (from memory):  A perfect number is a number which is equal to the cube
>of its component digits summed -- that is, 153 is a perfect number because it is
>equal to 1*1*1 + 5*5*5 + 3*3*3.  Code a COBOL program to find the perfect numbers
>between 100 and 999.
>I came up with this, but I'm not convinced that this is the right approach -- beyond
>the apparent problems with this code itself.

snip...snip...

try
01 my-number pic 9999.
01 filler redefines my-number.
   05 filler pic 9.
   05 my-hun pic 9.
   05 my-dec pic 9.
   05 my-one pic 9.

perform varying my-number from 100 by 1 until my-number = 1000
   ....
   compute test-num = my-hun ** 3 + my-dec ** 3    etc.

JR

and stir with a Runcible spoon...



Tue, 06 Oct 1998 03:00:00 GMT  
 Finding perfect numbers

Quote:

>     01  Hundreds                PIC   9 Value Zeros.
>     01  Tens                    PIC   9 Value Zeros.
>     01  Ones                    PIC   9 Value Zeros.
>     01  Test-Number             PIC 999 Value Zeros.
[...]
>     Perform Tester
>         Varying Hundreds from 1 by 1 Until Hundreds > 9
>             After Tens from 0 by 1 Until Tens > 9
>                 After Ones from 0 by 1 Until Ones > 9.
[...]
> I don't think I handled the varying clause correctly . . . I need the
> digits to hit and include '9' before stopping but what happens when
> they hit '10' but are only PIC 9s

Think of each "9" in a picture as one wheel in your car's odometer.  The
value 9 rolls over to the value 0.  For example, in this program the
variable ONES will take on the values 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,
2, ...

ONES can never be greater than 9, so TENS will never be incremented.
TENS can never be greater than 0, so HUNDREDS will never be incremented.
HUNDREDS can never be greated than 1 so your loop will never terminate.
TEST-NUMBER will take on the values 100, 101, 102, 103, 104, 105, 106,
107, 108, 109, 100, 101, ...

All those 01-levels indicate that you are not yet comfortable with
CoBOL's hierarchical structure.  Consider this:

    01  Test-Number   PIC  9(3).
    01  Filler        Redefines Test-Number.
        05  Hundreds  PIC  9(1).
        05  Tens      PIC  9(1).
        05  Ones      PIC  9(1).

    Perform Tester
        Varying Test-Number from 100 by 1 Until Test-Number = ZERO.

Quote:
>     Tester.

>         String  Hundreds delimited by size
>                 Tens delimited by size
>                 Ones delimited by size
>           Into  Test-Number.

>         Compute Test-Case = (Hundreds * Hundreds * Hundreds) +
>                             (Tens * Tens * Tens) +
>                             (Ones * Ones * Ones).

>         If Test-Case = Test-Number
>             Display Test-Number ' is a perfect number'
>             Add 1 to Perfect-Number-Counter.

One thing about any computer language, including CoBOL, is that it will
cheerfully do whatever you say.  Consider this:

    Tester.

        If   Hundreds * Hundreds * Hundreds
        +    Tens * Tens * Tens
        +    Ones * Ones * Ones
        =    Test-Number
        Then Display Test-Number ' is a perfect number'
             Add 1 to Perfect-Number-Counter
        End-if.

There's still a long way to go from here to a good program, but at least
this one terminates!  Remember, programing is not knowledge acquired by
memorization, it is skill acquired by practice.  These little problems
are posed merely to give you a reason to grapple with the syntax until
you have it at your fingertips, not to find the answers, which are, of
course, well known.

--
Christopher Westbury, Midtown Associates, 15 Fallon Place, Cambridge, MA 02138



Tue, 06 Oct 1998 03:00:00 GMT  
 Finding perfect numbers

Quote:

>>I took an examination in my COBOL class earlier this evening and was troubled by
>>one of the test questions.  I know it's one of those "too easy to be easy" questions.

>>If it's not out of line, I thought I would post the question and my thoughts on it,
>>then ask for feedback.

>>Question (from memory):  A perfect number is a number which is equal to the cube
>>of its component digits summed -- that is, 153 is a perfect number because it is
>>equal to 1*1*1 + 5*5*5 + 3*3*3.  Code a COBOL program to find the perfect numbers
>>between 100 and 999.

>>I came up with this, but I'm not convinced that this is the right approach -- beyond
>>the apparent problems with this code itself.

>snip...snip...

>try
>01 my-number pic 9999.
>01 filler redefines my-number.
>   05 filler pic 9.
>   05 my-hun pic 9.
>   05 my-dec pic 9.
>   05 my-one pic 9.

>perform varying my-number from 100 by 1 until my-number = 1000
>   ....
>   compute test-num = my-hun ** 3 + my-dec ** 3    etc.

>JR

>and stir with a Runcible spoon...

Let us all know what we are talking about;  Pythagoras (582-500BC)
saw perfection in any whole number that equalled the sum of all its
divisors (except the number itsel).  The first perfect number is 6
(6 is divible by 1,2, and 3 and 6 is also = 1+2+3).  The second
perfect number is 28.  Then follows 496 and 8,128.
This much the ancient Greeks knew.
The perfection of 6 and 28 is also mentioned in the bible and is
reflected in the structure of the universe: God created the World
in 6 days, and the moon orbits the Earth in 28 days.  Yet is the
numbers themselves that are perfect.
Perfection is always hard to come by.  Only thirty perfect numbers
are known, the largest being the 130,000 digit monster equal to
2**216,090*(2**216,090 - 1).  For more than two thousand
years we have kown that there are infinitely many prime numbers,
but we do not know if that is the case also for perfect numbers.
But already Euclid know that the formula 2**(n-1)*(2**n-1)
generates an even perfect number whenever 2**n-1 is prime.
No ODD perfect number is known.
So, perfect numbers have nothing to do with cubes of constituent
digits.


Tue, 06 Oct 1998 03:00:00 GMT  
 Finding perfect numbers

Quote:


> >    01  Test-Number   PIC  9(3).
> >    01  Filler        Redefines Test-Number.
> >        05  Hundreds  PIC  9(1).
> >        05  Tens      PIC  9(1).
> >        05  Ones      PIC  9(1).

> >    Perform Tester
> >        Varying Test-Number from 100 by 1 Until Test-Number = ZERO.

> Maybe we should say BY -1 here instead of BY 1; it might help making
> progress towards termination.

Couple of things at once here.  

First, on the 'perfect number' issue I stand corrected.  Even Webster's
Dictionary gets this right -- and I didn't.

Second, thanks to all who made suggestions about my code.  I admitted
up front that knew I blew this one on the test.  As usual, I was bent
on making things more difficult than they needed to be.  The posts
suggested some straightforward, solid and _simple_ ways to handle the
problem.  I learned, and I thank you.

Finally, the +1 increment (as opposed to a -1 decrement) does work.  
The code below is exported directly from my compiler; it is verbatim
except for changing references to "perfect numbers" :)  It compiles
and runs without error, displaying four numbers.

       IDENTIFICATION DIVISION.
       Program-ID.              NotPerfectNumbers.

       DATA DIVISION.
       Working-Storage Section.
       01  Test-Num            PIC 999.
       01  Test-Digits Redefines Test-Num.
           05  Huns            PIC 9.
           05  Tens            PIC 9.
           05  Ones            PIC 9.

       Procedure Division.
       Mainline.
           Perform Varying Test-Num from 100 by 1 Until Test-Num = 000
             If ((Huns ** 3) + (Tens ** 3) + (Ones ** 3)) = Test-Num
               Display Test-Num ' is not a perfect number'
                 End-if
                   End-Perform.

My thinking is that this works because the +1 increment causes the
value '1000' to be placed in the Test-Num field but, because of
COBOL's right-to-left movement of numbers, only the last three digits
are stored in the field.  

Thus, the '= 000' test works.

Thanks again to all who posted.

John Streeter



Tue, 06 Oct 1998 03:00:00 GMT  
 Finding perfect numbers
Yes, you are missing something obvious -- in the way you combine the digits to make
test-number.  Instead of STRINGing them together, COMPUTE the value, e.g.
        COMPUTE test-number = 100 * hundreds + 10 * tens + ones.
Then you can make the digits PIC 99 as they must be to hold values > 9 without corrupting
the value of test-number.

+I took an examination in my COBOL class earlier this evening and was troubled by
+one of the test questions.  I know it's one of those "too easy to be easy" questions.
+
+If it's not out of line, I thought I would post the question and my thoughts on it,
+then ask for feedback.
+
+Question (from memory):  A perfect number is a number which is equal to the cube
+of its component digits summed -- that is, 153 is a perfect number because it is
+equal to 1*1*1 + 5*5*5 + 3*3*3.  Code a COBOL program to find the perfect numbers
+between 100 and 999.
+
+I came up with this, but I'm not convinced that this is the right approach -- beyond
+the apparent problems with this code itself.
+
+       Data Division.
+       Working-Storage Section.
+       01  Hundreds                PIC   9 Value Zeros.
+       01  Tens                    PIC   9 Value Zeros.
+       01  Ones                    PIC   9 Value Zeros.
+       01  Test-Case               PIC 999 Value Zeros.
+       01  Test-Number             PIC 999 Value Zeros.
+       01  Perfect-Number-Counter  PIC  99 Value Zeros.
+
+       Procedure Division.
+       Mainline.
+           Perform Tester
+               Varying Hundreds from 1 by 1 Until Hundreds > 9
+                   After Tens from 0 by 1 Until Tens > 9
+                       After Ones from 0 by 1 Until Ones > 9.
+           Display Perfect-Number-Counter ' perfect numbers found.'.
+           Stop Run.
+
+       Tester.
+           String  Hundreds delimited by size
+                   Tens delimited by size
+                   Ones delimited by size
+                       Into Test-Number.
+           Compute Test-Case = (Hundreds * Hundreds * Hundreds) +
+                               (Tens * Tens * Tens) +
+                               (Ones * Ones * Ones).
+           If Test-Case = Test-Number
+               Display Test-Case ' is a perfect number'
+               Add 1 to Perfect-Number-Counter.
+
+I don't think I handled the varying clause correctly . . . I need the digits to hit
+and include '9' before stopping but what happens when they hit '10' but are only PIC 9s
+-- my thinking is that I get a '0' b/c or right-left numeric movement, but more
+importantly, this means a loop.  If I use '= 9' then I will stop at 888.  Should I have
+made the digits all PIC 99's?  That changes the string . . . This seems to be getting real
+big, real quick.  I must be missing something obvious.
+
+How close am I to an (the) answer?  By the way, the test _is_ over :)
+
+John S.



Tue, 06 Oct 1998 03:00:00 GMT  
 Finding perfect numbers

Quote:

>>I took an examination in my COBOL class earlier this evening and was troubled by
>>one of the test questions.  I know it's one of those "too easy to be easy" questions.

>>If it's not out of line, I thought I would post the question and my thoughts on it,
>>then ask for feedback.

>>Question (from memory):  A perfect number is a number which is equal to the cube
>>of its component digits summed -- that is, 153 is a perfect number because it is
>>equal to 1*1*1 + 5*5*5 + 3*3*3.  Code a COBOL program to find the perfect numbers
>>between 100 and 999.

>JR

>and stir with a Runcible spoon...

BTW, apart from the fact that 153 is NOT a perfect number (see my
other post about that) it IS an interesting number.  In the Gospel according
to John (21:11) Jesus and His disciples have a successful fishing trip.
When they haul in the catch they find 153 fish.  There is more:
153 = 1+2+3+...14+15+16+17 (sum of the first 17 integers).
How about this one: 153 = 1!+2!+3!+4!+5! (where n! = 1*2*3*...*(n-1)*n),
and, of course, also 153 = 1**3 + 5**3 + 3**3.
It gets better: take any number, multiply it by three, then sum the cubes of
its digits, take the result and sum the cubes of its digits; keep doing this,
and you always end up with 153.  So Jesus knew (as the almighty is prone
to do) that 153 is very special, but is not a perfect number.


Wed, 07 Oct 1998 03:00:00 GMT  
 Finding perfect numbers

Quote:


>>     01  Hundreds                PIC   9 Value Zeros.
>>     01  Tens                    PIC   9 Value Zeros.
>>     01  Ones                    PIC   9 Value Zeros.
>>     01  Test-Number             PIC 999 Value Zeros.
>[...]
>>     Perform Tester
>>         Varying Hundreds from 1 by 1 Until Hundreds > 9
>>             After Tens from 0 by 1 Until Tens > 9
>>                 After Ones from 0 by 1 Until Ones > 9.
>[...]
>> I don't think I handled the varying clause correctly . . . I need the
>> digits to hit and include '9' before stopping but what happens when
>> they hit '10' but are only PIC 9s

>Think of each "9" in a picture as one wheel in your car's odometer.  The
>value 9 rolls over to the value 0.  For example, in this program the
>variable ONES will take on the values 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0, 1,
>2, ...

>ONES can never be greater than 9, so TENS will never be incremented.
>TENS can never be greater than 0, so HUNDREDS will never be incremented.
>HUNDREDS can never be greated than 1 so your loop will never terminate.
>TEST-NUMBER will take on the values 100, 101, 102, 103, 104, 105, 106,
>107, 108, 109, 100, 101, ...

>All those 01-levels indicate that you are not yet comfortable with
>CoBOL's hierarchical structure.  Consider this:

>    01  Test-Number   PIC  9(3).
>    01  Filler        Redefines Test-Number.
>        05  Hundreds  PIC  9(1).
>        05  Tens      PIC  9(1).
>        05  Ones      PIC  9(1).

>    Perform Tester
>        Varying Test-Number from 100 by 1 Until Test-Number = ZERO.

Maybe we should say BY -1 here instead of BY 1; it might help making
progress towards termination.
s delimited by size

- Show quoted text -

Quote:
>>                 Tens delimited by size
>>                 Ones delimited by size
>>           Into  Test-Number.

>>         Compute Test-Case = (Hundreds * Hundreds * Hundreds) +
>>                             (Tens * Tens * Tens) +
>>                             (Ones * Ones * Ones).

>>         If Test-Case = Test-Number
>>             Display Test-Number ' is a perfect number'
>>             Add 1 to Perfect-Number-Counter.

>One thing about any computer language, including CoBOL, is that it will
>cheerfully do whatever you say.  Consider this:

>    Tester.

>        If   Hundreds * Hundreds * Hundreds
>        +    Tens * Tens * Tens
>        +    Ones * Ones * Ones
>    =    Test-Number
>        Then Display Test-Number ' is a perfect number'
>             Add 1 to Perfect-Number-Counter
>        End-if.

>There's still a long way to go from here to a good program, but at least
>this one terminates!  Remember, programing is not knowledge acquired by
>memorization, it is skill acquired by practice.  These little problems
>are posed merely to give you a reason to grapple with the syntax until
>you have it at your fingertips, not to find the answers, which are, of
>course, well known.

>--
>Christopher Westbury, Midtown Associates, 15 Fallon Place, Cambridge, MA 02138



Wed, 07 Oct 1998 03:00:00 GMT  
 Finding perfect numbers

Quote:



> > >    01  Test-Number   PIC  9(3).
> > >    01  Filler        Redefines Test-Number.
> > >        05  Hundreds  PIC  9(1).
> > >        05  Tens      PIC  9(1).
> > >        05  Ones      PIC  9(1).

> > >    Perform Tester
> > >        Varying Test-Number from 100 by 1 Until Test-Number = ZERO.

> > Maybe we should say BY -1 here instead of BY 1; it might help making
> > progress towards termination.

> Couple of things at once here.

> First, on the 'perfect number' issue I stand corrected.  Even Webster's
> Dictionary gets this right -- and I didn't.

> Second, thanks to all who made suggestions about my code.  I admitted
> up front that knew I blew this one on the test.  As usual, I was bent
> on making things more difficult than they needed to be.  The posts
> suggested some straightforward, solid and _simple_ ways to handle the
> problem.  I learned, and I thank you.

> Finally, the +1 increment (as opposed to a -1 decrement) does work.
> The code below is exported directly from my compiler; it is verbatim
> except for changing references to "perfect numbers" :)  It compiles
> and runs without error, displaying four numbers.

>        IDENTIFICATION DIVISION.
>        Program-ID.              NotPerfectNumbers.

>        DATA DIVISION.
>        Working-Storage Section.
>        01  Test-Num            PIC 999.
>        01  Test-Digits Redefines Test-Num.
>            05  Huns            PIC 9.
>            05  Tens            PIC 9.
>            05  Ones            PIC 9.

>        Procedure Division.
>        Mainline.
>            Perform Varying Test-Num from 100 by 1 Until Test-Num = 000
>              If ((Huns ** 3) + (Tens ** 3) + (Ones ** 3)) = Test-Num
>                Display Test-Num ' is not a perfect number'
>                  End-if
>                    End-Perform.

> My thinking is that this works because the +1 increment causes the
> value '1000' to be placed in the Test-Num field but, because of
> COBOL's right-to-left movement of numbers, only the last three digits
> are stored in the field.

> Thus, the '= 000' test works.

> Thanks again to all who posted.

> John Streeter

Until somebody modifies your code,  too many maintenance programmers
have lost sleep trying to figure what is causing a program to go down,
with the original programmer being a little to clever to keep it simple.
3 am logic is going to say "Why on earth is he adding to field and then
comparing it to zero". I know of no program that has never undergone
modification for some change in functionality, that count field may well
be used for some other reason later, it could be expanded, used as a
subscript, whatever.  KISS is a rule of thumb all programmers should
adhere to, if just for the poor guy on call at night.


Wed, 07 Oct 1998 03:00:00 GMT  
 Finding perfect numbers

Quote:



>> > >    01  Test-Number   PIC  9(3).
>> > >    01  Filler        Redefines Test-Number.
>> > >        05  Hundreds  PIC  9(1).
>> > >        05  Tens      PIC  9(1).
>> > >        05  Ones      PIC  9(1).

>> > >    Perform Tester
>> > >        Varying Test-Number from 100 by 1 Until Test-Number = ZERO.

>> > Maybe we should say BY -1 here instead of BY 1; it might help making
>> > progress towards termination.

>> Couple of things at once here.

>> First, on the 'perfect number' issue I stand corrected.  Even Webster's
>> Dictionary gets this right -- and I didn't.

>> Second, thanks to all who made suggestions about my code.  I admitted
>> up front that knew I blew this one on the test.  As usual, I was bent
>> on making things more difficult than they needed to be.  The posts
>> suggested some straightforward, solid and _simple_ ways to handle the
>> problem.  I learned, and I thank you.

>> Finally, the +1 increment (as opposed to a -1 decrement) does work.
>> The code below is exported directly from my compiler; it is verbatim
>> except for changing references to "perfect numbers" :)  It compiles
>> and runs without error, displaying four numbers.

>>        IDENTIFICATION DIVISION.
>>        Program-ID.              NotPerfectNumbers.

>>        DATA DIVISION.
>>        Working-Storage Section.
>>        01  Test-Num            PIC 999.
>>        01  Test-Digits Redefines Test-Num.
>>            05  Huns            PIC 9.
>>            05  Tens            PIC 9.
>>            05  Ones            PIC 9.

>>        Procedure Division.
>>        Mainline.
>>            Perform Varying Test-Num from 100 by 1 Until Test-Num = 000
>>              If ((Huns ** 3) + (Tens ** 3) + (Ones ** 3)) = Test-Num
>>                Display Test-Num ' is not a perfect number'
>>                  End-if
>>                    End-Perform.

>> My thinking is that this works because the +1 increment causes the
>> value '1000' to be placed in the Test-Num field but, because of
>> COBOL's right-to-left movement of numbers, only the last three digits
>> are stored in the field.

>> Thus, the '= 000' test works.

>> Thanks again to all who posted.

>> John Streeter

>Until somebody modifies your code,  too many maintenance programmers
>have lost sleep trying to figure what is causing a program to go down,
>with the original programmer being a little to clever to keep it simple.
>3 am logic is going to say "Why on earth is he adding to field and then
>comparing it to zero". I know of no program that has never undergone
>modification for some change in functionality, that count field may well
>be used for some other reason later, it could be expanded, used as a
>subscript, whatever.  KISS is a rule of thumb all programmers should
>adhere to, if just for the poor guy on call at night.

The KISS version of the perform statement would have been:
   Perform varying test-num from 100 by 1 until test-num > 999
Unfortunately, that will not work because test-num will NEVER be
greater than 999 as it roll over from 999 to 000 because of its
picture clause.  I don't think John was being clever here (maybe
he can tell us himself?); I think he was just desperate.
The real question is: what SHOULD he had done?  The problem
occurs often enough to warrant a discussion in this Forum.

Some alternatives:
1) test against = 999, but with test AFTER.  Since this is not
   supported in COBOL-74, this may not be the best solution.
   (writing portable software, I cannot use AFTER).
2) perform varying from 999 by -1 until 0
   will work, but is unnatural because we may want the results
   in their natural increasing order; even if we did use -1, a
   maintenance programmer might change the perform statement
   to use increasing order because the end-users were complaning
   about the results being printed with the largest first.
3) use a different variable for the loop,
   eg.  02  loop-count   pic s9(4) comp.
   and then
        perform find-perfect-number
          varying loop-count from 100 by 1
             until loop-count > 999

  find-perfect-number.
       move loop-count to test-num
       if ....

   This is the solution I would use, but it is not good: there is
   an extra variable to maintain.  If we wish to find "perfect"
   numbers (actually not perfect - see earlier postings) up to
   99999, we would have to change TWO picture clauses instead
   of one.

There is no good solution (except using AFTER, which won't port
down to COBOL-74).  The Ada programming language has solved the
problem within the language by specifying that numbers which are
used to index an array (the most common use of loops) are always
defined to be at least one larger than the highest value of the
subscript, but COBOL has no such stipulation.
THERE  IS  NO  GOOD  SOLUTION.



Thu, 08 Oct 1998 03:00:00 GMT  
 Finding perfect numbers

Quote:
> THERE  IS  NO  GOOD  SOLUTION.

What about this one?

01  Test-Num    pic 9(4).
01  filler redefines Test-Num.  
     05  filler     pic x.
     05  Hundreds   pic 9.
     05  Tens       pic 9.  
     05  Ones       pic 9.

You can now use 'until Test-Num > 999'    



Thu, 08 Oct 1998 03:00:00 GMT  
 Finding perfect numbers

Quote:

>> THERE  IS  NO  GOOD  SOLUTION.

>What about this one?

>01  Test-Num    pic 9(4).
>01  filler redefines Test-Num.  
>     05  filler     pic x.
>     05  Hundreds   pic 9.
>     05  Tens       pic 9.  
>     05  Ones       pic 9.

>You can now use 'until Test-Num > 999'    

Will work in this particular case where the loop variable is of usage
DISPLAY.  Since this usage is VERY slow, it is much more likely
that the loop variable is of Usage COMPUTATIONAL (which cannot
be redefined in a system indedependent way) and it is here that we
have the general problem.


Thu, 08 Oct 1998 03:00:00 GMT  
 
 [ 22 post ]  Go to page: [1] [2]

 Relevant Pages 

1. New user need help with perfect numbers.

2. Perfect Numbers

3. Perfect Numbers

4. ASM to test Perfect Number

5. Perfect Number

6. Perfect Numbers, Complexity

7. Yet another perfect number program

8. Yet another perfect number program

9. perfect numbers

10. i found the perfect python web host with root access

11. Finding out number of threads or number of open windows in the app

12. Duel, Apl, and the shortest program to find prime numbers

 

 
Powered by phpBB® Forum Software