You should initialise sum
to zero within your function. Otherwise, it will be set to some arbitrary value and the else
block will have an arbitrary result.
In other words, change:
int sum;
into:
int sum = 0;
Of course, once you've done that, there's no need to explicitly do anything for the case where x
is less than one. In addition, the initial if
is superfluous since the for
body won't execute when x
is less than one, so you could get away with something like:
int sumDivisors (int x) {
int i, sum = 0;
for (i = 1 ; i < x; i++) {
if ((x % i) == 0) {
sum += i;
}
}
return sum;
}
As an aside, the values you're actually seeing without the initialisation are accumulating:
0 -> 0
0 -> 0
0 -> 0
3 -> 3
1 -> 4
6 -> 10
16 -> 26
This is almost certainly because each call to the function is reusing the same memory for the stack frame, including the variable sum
, so sum
is simply being added to each time (that the passed-in parameter is greater than one).
However, that's simply an artifact of the implementation, it's not guaranteed by the standard, which states quite clearly in C11 6.7.9 Initialization /10
:
If an object that has automatic storage duration is not initialized explicitly, its value is indeterminate.
In other words, don't rely on this.
And, as yet another aside, it's a mathematical given that, if a number n
divides evenly by a
, it also divides evenly by n/a
. You can use this to your advantage to possibly make the code a little more efficient (though, as with all optimisations, you should measure, not guess).
Since you're discounting the number itself as a divisor, you have to treat the divisor 1
as a special case. You also have to treat perfect squares as a special case so that you don't add the square root twice.
The following code would be a good starting point for that:
int sumDivisors (int x) {
int i, sum;
// Always return zero for -inf..1 inclusive.
if (x < 2)
return 0;
// Otherwise, 1 is factor, search for others
// up to but NOT including sqrt(x).
for (i = 2, sum = 1 ; i * i < x; i++) {
if ((x % i) == 0) {
sum += i;
sum += x / i;
}
}
// Add in sqrt(x) ONCE for a perfect square.
if (i * i == x)
sum += i;
return sum;
}