I tried to improve the iterative version:
unsigned int sum2_improved(unsigned int from, unsigned int to) { int p = to - from; if (p == 0) return from; int x = to + from; int s = 0; int i; for (i = p >> 1; i > 0; i--) { s += x; } s += (p % 2 == 0) ? x >> 1 : x; return s; }
I tested your version with:
for (i = 0; i < 9999999; i++) sum2(1,999);
Here is what I see:
$ time ./addm real 0m18.315s user 0m18.220s sys 0m0.015s
I tried my implementation with the same number of loops. Here, how the improved function is implemented:
$ time ./addm real 0m14.196s user 0m14.070s sys 0m0.015s
UPDATE
In my implementation, x = to + from is the sum of the first and last number in the sequence. If you consider any consecutive sequence of integers and sum the first and last, second and second to last, etc ... all these sums coincide with the same value. For example, in (1 ... 6), 1 + 6 = 2 + 5 = 3 + 4 = 7 . However, with a sequence containing an odd number of elements, you are left with the average number that you will need to add to the total (which is what was done after the for loop.
Also note that this is still O(n) . I realized that after I stated my answer, my approach can indeed be carried out in a constant time. Here's the updated code:
unsigned int sum0(unsigned int from, unsigned int to) { int p = to - from; if (p == 0) return from; int x = to + from; int s = 0; s += (x * (p >> 1)); s += (p % 2 == 0) ? x >> 1 : x; return s; }
I ran this with the same number of loops as the previous tests. Here is what I saw:
$ time ./addm real 0m0.158s user 0m0.093s sys 0m0.047s
I am not sure if this can be considered as a variant of the formula for your purposes. In any case, it was an interesting exercise for me.