Finding perfect numbers 
Author Message
 Finding perfect numbers

[snip]

Quote:

> >>        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.

[snip]

- Show quoted text -

Quote:
> >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.

[snip]

John's Response:

First, the code above is not my original effort -- it's something I
threw together incorporating two or three suggestions from contributors
to this discussion to prove one point: a loop incrementing a PIC 999 field
by 1 from 100 can be stopped with an '= 000' test.

This isn't me being clever -- my original code shows that I missed that
opportunity to be clever as well as the opportunity to be *right* :)  

I like the approach of using a PIC 9999, redefining it to include a
leading filler space, then testing it with '> 999' to stop the loop.
This is indeed more recognizable to *me* -- forget the maintainence
programmers.  My post was responding specifically to a point made
about the suggestion to test for '= 000' instead of '> 999'.  In this
limited application, and given the fact that we start from a non-zero
integer (i.e. 100), we can "roll over" the 999 to 000 with +1 increments.  

I know this is not necessarily good or even clever; it does, however,
prove the point about terminating the loop -- which is the only reason
I posted this version of the code.

--John

BTW, we have not received our graded tests back yet -- it will be very
interesting to hear the class discussions about what the "right" answer(s)
should have been . . .



Fri, 09 Oct 1998 03:00:00 GMT  
 Finding perfect numbers

Quote:

> 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 too clever to keep it
> simple.  3 am logic is going to say "Why on earth is he adding to a
> 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.

Your concern is commendable, but misplaced in an educational context.

It is hard to come up with a problem that can teach a concept but still
be even slightly realistic.

In this case, it is a basic fact of computer hardware that all fields
roll over, like the odometer in your car.  A two-byte two's-complement
binary field rolls over from 32767 to -32768, a two-byte packed-decimal
field rolls over from 999 to 000, etc.  If you don't know this, you will
get into trouble in any language, not just in CoBOL.

Of course, after you learn the concept, you realize that the problem was
artificial, posed only to get you thinking about the concept, and you
would not do it that way in real life.

You can't write a real program when all you've got is an examination
problem, and you can't practice the rudiments of CoBOL in a real program.
Don't ask for more from these toy programs than they can give.

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



Sat, 10 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.

You can make any number of different pedagogical points with these toy
problems.  I think that the Data Division is harder to teach and more
misunderstood than any other aspect of CoBOL.  I limited the number of
points I made to improve the odds that some of my points would be taken.

Of course, loop control is an important subject, and "BY -1" is a useful
technique that is too often forgotten.

But if you want to make a point, make it, don't just allude to it!
Write the thing, run it through a compiler to check it, and post it:

    Perform Tester
        Varying Test-Number from 999 by -1 Until Test-Number = "099".

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



Sat, 10 Oct 1998 03:00:00 GMT  
 Finding perfect numbers
Quote:



> > 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 too clever to keep it
> > simple.  3 am logic is going to say "Why on earth is he adding to a
> > 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.

> Your concern is commendable, but misplaced in an educational context.

> It is hard to come up with a problem that can teach a concept but still
> be even slightly realistic.

> In this case, it is a basic fact of computer hardware that all fields
> roll over, like the odometer in your car.  A two-byte two's-complement
> binary field rolls over from 32767 to -32768, a two-byte packed-decimal
> field rolls over from 999 to 000, etc.  If you don't know this, you will
> get into trouble in any language, not just in CoBOL.

> Of course, after you learn the concept, you realize that the problem was
> artificial, posed only to get you thinking about the concept, and you
> would not do it that way in real life.

> You can't write a real program when all you've got is an examination
> problem, and you can't practice the rudiments of CoBOL in a real program.
> Don't ask for more from these toy programs than they can give.

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

I do not think that good programming practice is misplaced in any field.
As this news group is read by all people interested in COBOL, not only
students but first and second year programmers, I think we should do our
best to promote good code.  I have programmed in COBOL since 1978 and
find usefull information in this group.  I am also aware of the rolling
of numeric numbers, mainly thru solving abends caused by zero subscripts
on numeric arrays.  The major reasons for these abends are; not
initializing the subscript, not checking the subscript, and not having
the subscript declared large enough to account for all the rows in the
table.  As this is a COBOL group, I will treat all COBOL programs with
the respect they deserve. When I was at college my examination answers
were punched up, compiled and run, and given back to a fellow student to
fix, whilst I tried to debug some other students program. Our little
masterpieces were then critiqued, and we were amazed that our fellows
could not easily follow what we thought we glaring examples of pure
logic.  My education actually prepared me quite well for the real world
of COBOL programming.


Sat, 10 Oct 1998 03:00:00 GMT  
 Finding perfect numbers

Quote:

> The real question is: what SHOULD he have done?  The problem occurs
> often enough to warrant a discussion in this forum.

Considering only statements that are at most one baby step away from the
original statements, the most economical loop is:

    01  Test-Number   PIC  9(3) Value 100.
    01  FILLER        REDEFINES  Test-Number.
        05  Hundreds  PIC  9(1).
        05  Tens      PIC  9(1).
        05  Ones      PIC  9(1).

    01  Ws-Counter    PIC  9(1) Value Zero.

    Display "Numbers that equal the sum of the cubes of their digits:".

    Perform 900 times

        If   Test-Number = Hundreds**3 + Tens**3 + Ones**3
        Then Add 1 to Ws-Counter
             Display Ws-Counter ". " Test-Number
        End-if

        Add 1 to Test-Number

    End-perform.

Extra credit to anyone who knows why this is so, but points off for
complaining about the IF-statement.

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



Sun, 11 Oct 1998 03:00:00 GMT  
 Finding perfect numbers

Quote:

> I like the approach of using a PIC 9999, redefining it to include a
> leading filler space, then testing it with '> 999' to stop the loop.
> This is indeed more recognizable to *me* -- forget the maintenance
> programmers.

CoBOL was equipped with a rich set of control structures so that you can
implement any algorithm without resorting to such expedients.  A
mysterious FILLER in the Data Division is logically no better than a
mysterious statement in the Procedure Division.  It's just considered
more acceptable (by some) because fewer people understand the Data
Division.  Consider how these two loops work:

    Perform Tester
        With test before
            Varying Test-Number from 100 by 1
                Until Test-Number = "000".

    Perform Tester
        With test after
            Varying Test-Number from 100 by 1
                Until Test-Number = "999".

Even the nonterminating loop you originally posted:

    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.

can be made to terminate thusly:

    Perform Tester
        With test after
            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.

Here is the output from your posted program with this change:

    $ cobol demo.cob
    $ link demo.obj
    $ run demo.exe
    153 is a perfect number
    370 is a perfect number
    371 is a perfect number
    407 is a perfect number
    04 perfect numbers found.
    $

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



Sun, 11 Oct 1998 03:00:00 GMT  
 Finding perfect numbers

Quote:



> > I like the approach of using a PIC 9999, redefining it to include a
> > leading filler space, then testing it with '> 999' to stop the loop.
> > This is indeed more recognizable to *me* -- forget the maintenance
> > programmers.

> CoBOL was equipped with a rich set of control structures so that you can
> implement any algorithm without resorting to such expedients.  A
> mysterious FILLER in the Data Division is logically no better than a
> mysterious statement in the Procedure Division.  It's just considered
> more acceptable (by some) because fewer people understand the Data
> Division.  Consider how these two loops work:[snip]
> Even the nonterminating loop you originally posted:[snip]
> can be made to terminate thusly:

>     Perform Tester
>         With test after
>             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.
> [snip]

My comment was meant to indicate that I would understand more quickly what
the code was doing if I saw 'do x until y > 999' rather than 'do x until
y = 0' where y is *incremeneted* rather than *decremented.*  But the logic
of the final code snippet seems more obvious than either of the above; I
read it 'do x until y = 999 -- and include 999'.

Final thoughts on 'Re: Finding perfect numbers':

1.      Given that COBOL-85 code would have been OK on the exam, I
        should have taken advantage of 'with test after' to stop my
        loop at 999 inclusive.  

2.      I'm annoyed that I mishandled the mechanics of stopping the
        program; more so, however, that I bungled the logic.  I don't
        care as much about getting the code wrong a couple of times
        as I do about trying to do simple redefines with complicated
        and wasteful moves.  As long as I can figure out how to do
        the right thing (see #4), I'll eventually figure out how to
        stop it correctly.

3.      I've picked up many new techniques from the comments and
        suggestions; even if I don't work them into this code,  they're
        in my toolbox now.  Thank you.

3.      Chris Westbury pointed out that 2,690 of my 2,700 cube
        calculations were redundant . . . I only need cubed-values
        for 0,1,2 . . . 9.  JES2 log shows an execute time of .22
        seconds against .85 +/- for runtime calculations.  Cool.
        Thanks, Chris.

--
John Streeter
--



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

 Relevant Pages 
 

 
Powered by phpBB® Forum Software