THE PUZZLET PAGE


How_Does_It_Work


FUNCTION:  IsOddAbundant().  An Abundant Number is one for which the sum of its proper divisors is greater than the number itself. The proper divisors are those integers which divide into the number, which includes 1 but excludes the number itself.

Example: 12's proper divisors are 1, 2, 3, 4, 6. These add up to 16, which is greater than 12, so 12 is Abundant.  Odd Abundant numbers are quite rare, the smallest being 945.

When an integer is passed to IsOddAbundant(), the function checks its Odd Abundancy. If it's Odd Abundant, TRUE (-1) is returned, otherwise FALSE (0).

It's up to you what kind of integer you pass to the function, as long as the function declaration has already taken this data-typing into account. See the table below for the parameter limits.

Type

Exponent of 2
Value

int 230 1073741824
uint 231 2147483648
int64 261 2305843009213693952
uint64 262 4611686018427387904

Declaring the function must be done like this:

declare IsOddAbundant(a: int) (or whatever integer type you want).

Here's the code:


sub IsOddAbundant(a)
' If argument a is an odd abundant
' number, returns TRUE, otherwise
' returns FALSE.
' By Dave Ellis.
if a % 2 = 0: 'not an odd number!
    return 0
endif
def fin, fctr, flag, tot: int
fin = a/3: 'maximum of search range
tot = 1:
'mininum factor
fctr = 3: 'next factor
flag = 0
do
    if a % fctr = 0
        tot = tot + fctr
    endif
    fctr = fctr + 2
until fctr > fin
if tot > a
    flag = -1
endif
return flag

Overview:  The function opens by checking that its argument isn't an even number, which would defeat the object of the exercise!  Then it searches for factors of its argument, a.  Since we are only interested in odd numbers, it begins at 3 and checks only for odd factors.  The highest factor checked is a/3, since the is greatest possible factor of an odd number.

Every time it finds a factor it's totalised into variable tot.  When all potential factors in the range have been processed in this way, the value stored in tot is compared with argument a.  If tot is greater, the argument is Abundant, and TRUE (-1) is returned, otherwise FALSE (0).

To make it simpler to follow a detailed code description, I've numbered the lines as shown below.


1
2
3
4
5
6
7
8
9
10
11
12
13
14

fin = a/3: 'maximum of search range
tot = 1:
'mininum factor
fctr = 3: 'next factor
flag = 0
do
    if a % fctr = 0
        tot = tot + fctr
    endif
    fctr = fctr + 2
until fctr > fin
if tot > a
    flag = -1
endif
return flag

Now for a line-by-line exegesis of the code.

1

fin = a/3.  Variable fin holds the "finish" value for the search range.  Because we are dealing with odd numbers here, the maximum factor must be the value stored in variable a (the function's argument), so fin is set to a/3.

2

tot = 1.  Variable tot will hold the totalised sum of all of a's factors.  All abundant numbers have 1 as a proper divisor, so tot's value is initialised to 1 to save the unnecessary check, and the search range commenced at 3 (see next line). 

3

fctr = 3.  The argument a is an odd number, so the smallest possible factor after 1 (already allowed for in line 2) will be 3, and this line initialises the variable that will be used to hold the factor currently being investigated, fctr, to 3.

4

flag = 0.  Variable flag will be used to indicate the result of the operation. It's initialised here to zero, FALSE.  If the argument is found to be an Odd Abundant number, flag will be set to -1, TRUE.

5

do.  Opens the main do-until loop.

6

if a % fctr = 0.  Line 6 uses integer arithmetic.  The % sign indicates that the code is to look only at the remainder of the operation.  So it can be paraphrased as "Is the remainder when the value stored in argument a is divided by the value stored in variable fctr equal to zero?"  In other words, does a divide exactly by fctr without remainder?

7

tot = tot + fctr.  Line 7 is only executed if the answer to the question in line 6 is "Yes."  This means that the current calue of fctr is a factor of argument a, so its value is added to that already saved in variable tot. The expression effectively says "Add the value saved in variable fctr to that of tot, and save the sum in variable tot, over-writing what was already in there."

8

endif.  Housekeeping - closes if-endif clause opened in line 6.

9

fctr = fctr + 2.  The value stored in variable fctr is incremented by 2.  This ensures that fctr's value remains odd - there would be no point in testing even-numbered factors on a declared odd number.

10

until fctr > fin.  The code has reached the end of the do-until loop at this point.  It has to make a decision: execute it again, or move on?  The value in variable fctr has been continually incremented by two's.  Eventually, it will be greater than that stored in variable fin, which, you will remember is the value set for the finish of the search.  So, line 10 says "If the value stored in variable fctr is now greater than that stored in variable fin quit the do-until loop, otherwise execute it again."

11

if tot > a.  By now, the code has quit the do-until loop and line 11 is the next instruction it encounters.  The question is asked "Is the value stored in variable tot greater than that stored in argument a?"  If the answer is in the affirmative, a must be holding an Odd Abundant Number, since the sum of it factors, or proper divisors, is greater than itself.

12

flag = -1.  Line 12 is only executed if the answer to the question posed in line 11 is "Yes."  It means that it  turns out the function's argument a is an Odd Abundant number, so flag  is set to TRUE (-1).

13

endif.  Housekeeping - closes if-endif clause opened in line 11.

13

return flag.  The function has concluded.  Whatever the value stored in variable flag, whether the initialised zero (FALSE) or altered to a -1 (TRUE), it is returned to the calling routine.


MAIN MENU
HOW DOES IT WORK?

Site design/maintenance: Dave Ellis E-mail me!
Last Updated: January 10th, 2010.