Re: Finding a perfect number.



In article <mn.e2c77d64119b5747.49793@xxxxxxxx>,
gk245 <topsoil@xxxxxxxx> wrote:
Trying to write a program that will figure out if a number is perfect
or not.

That's really an algorithm question, not a question about C.
algorithm questions are more topical in comp.programming and
other similar newsgroups.

Here is my logic:

1) Read in the number
2) Split it up (number - 1)
3) Put all the split up numbers into an array

I don't understand what you mean by "split it up", and I do not
understand how (number - 1) (step 2) is going to give you the
several numbers you expect to use to populate the array in step 3.


4) Figure out if the original number is evenly divisible by any of the
numbers in the array.
5) Add up only the numbers that devide the original number evenly in
the array.
6) Compare the total of these to the original number and give a yes or
no answer.

[OT for comp.lang.C]

You can do noticably better than that.

A perfect number is always of the form (2**N-1)*(2**(N-1)) where
I am here using ** to denote exponentiation. So you can shift bits
of your trial number to the right until you find that the bottom bit
is no longer a zero, counting the number of shifts as you go.
If what is left over does not have exactly the same number of bits as
you shifted, and if those bits are not all 1's, then the number is not
perfect. If that condition is satisfied, then you can test the shifted
number to determine whether it is prime: if it is, then the original
is a perfect number.

For example,
6 = (2**2-1)*(2**(2-1)) = 3*2
28 = (2**3-1)*(2**(3-1)) = 7*4


I started it, and here is how its coming out:

int main (void)

{
int number, i, split, total;
printf("Enter number: ");
scanf("%d", &number);
for (i =0 ; i <= number; i++)
{
int array[number];

That syntax is valid in C99 but not in C89. C89 does not allow
declaration of arrays with a length which is dynamically determined.
(The closest C89 equivilent is to use malloc() or calloc() to dynamically
allocate the necessary memory.)


split = number - 1;
number = split;
array[number] = split;

None of these steps have involved your variable i, so you might
as well have done them outside of the loop instead of inside the loop.
(That would require moving the declaration of array.)

I am concerned that you are declaring your array to have number
elements in it, but you are looping (number+1) times: it hints that
whatever you are thinking of probably has an off-by-one error.


printf("%d", array[number]); //just to check if the array
worked.

}
}

Obviously, this isn't even close to the solution, but i am getting
something, at least. Ofcourse, the program skips '1' and prints out
the rest up to only 5 digits. It won't 'split' the number any more.

I don't know what you mean by "split" in this matter, but the "5 digits"
offers a clue as to a possible explanation.

Your variable number is declared as an int, and your scanf() format is
"%d" which is the appropriate format for an int. But what is the
maximum size of signed int that your implementation supports? If
your signed int happens to be 16 bits long, then 1 bit is {effectively}
needed for the sign and 15 bits for the value, which would give a maximum
possible int of 32767 (32768 in very obscure implementations.)
And 32767 happens to be exactly 5 digits long.

You could try changing to variables of type long and using a "%ld" format
for the scanf(). Be warned, though, that implementations often do not
allow large arrays to be declared in the C99 way your are proceeding,
so if you go much larger than 32768 you might find the program crashing
for lack of memory. The adjustment to make for that would be to
malloc() the necessary memory instead (after sanity-checking the
size of the number!).
--
There are some ideas so wrong that only a very intelligent person
could believe in them. -- George Orwell
.



Relevant Pages

  • why cant array forward declarations be static?
    ... An array can be declared and used without the size being known, ... int get_foo ... The full definition can also come later in the same source file: ... that the forward declaration with static is perfectly reasonable although ...
    (comp.lang.c.moderated)
  • Re: Implicit int
    ... compile or implement, or even would have been in the 1970s. ... note that if you can't declare an array of size "n", ... could not already do with long int, had they chosen so to do. ... I recognise that this is not a popular view, but if the declaration is ...
    (comp.std.c)
  • Re: More proof of errors going uncorrected among the "regs"
    ... of a declaration of an object with incomplete type. ... I've worked with code that had an array declared like that. ... unit containing `int array;' at file scope and with no ...
    (comp.lang.c)
  • Re: Another C# marshaling question
    ... You will also have to change your function declaration to: ... public static extern int FF_Function( ... Then, what you have to do on return is marshal the array, like so: ... > public class FF_AO_OrderList ...
    (microsoft.public.dotnet.languages.csharp)
  • (patch for Bash) regex case statement
    ... Following up on my previous patch for regex conditional tests, ... /* Return an array of strings; ... int dollarflag, zeropad, compareflag; ... SHELL_VAR *var; ...
    (comp.unix.shell)