# Thread: Find the sum of all the multiples of 3 or 5 below 1000.

1. ## Find the sum of all the multiples of 3 or 5 below 1000.

Hi all I have written the following code in C language to 'Find the sum of all the multiples of 3 or 5 below 1000' it works fine for i<10 and i<100 and also gives the right answer but for condition i<1000 the answer is in -ve something like -28345. I am trying to understand waht is wrong and how to correct it. (I have a clue of what is wrong :-) but want to hear from the experts here)

Code:
```//Find the sum of all the multiples of 3 or 5 below 1000.
#include<stdio.h>
#include<conio.h>
void main ()
{
int a,b,i,iSum=0;
for (i=1;i<1000;i++)
{
a = i%3;
b = i%5;
if(a==0||b==0)
{
iSum = iSum+i;
}

}
printf("\nThe sum of all the multiples of 3 or 5 below 1000: %d\n", iSum);
getch();
clrscr();
}```

2. The sum is larger than 32768, so you need to use an integer type larger than 16 bits.

You can either use a modern compiler that produces 32-bit code, or change your code to use long int instead of int for the iSum variable.

--
Mats

3. At matsp said. You are hitting integer overflow. Also you may consider to use...

Code:
`   iSum += i;`

4. ## Thank you!

Thanks for the quick response matsp and slingerland. I did have a clue that the value for iSum was overflowing from int but was not very sure.I did change to iSum += i thanks again.

I tried with TurboC 3.X and TurboC++ 4.5 compilers and GCC 4.2.4 no success yet could you please suggest a decent 32 bit compiler that will run my program? (I am looking for a freeware.)

5. GCC is very well respected and is considered the de-facto standard. If it's not running your program, you should seriously consider why, and most likely follow the advice. I've used Turbo C 3.0 and 4.5 and really liked them - but they don't follow standard as strictly.

What kind of error messages are you getting with GCC? One thing that jumps out at me is that you use void main. main should return an int - some compilers allow it, but if I'm not mistaken, gcc doesn't.

edit: gcc also does not have conio.h - you would use ncurses instead. For simplicity's sake, you might as well just use conio.h on Turbo C.

6. Yeah, that void main() should have knocked me down. If you are entertaining any IDE's I use NetBeans which uses gcc as its compiler.

7. it runs perfectly well in gcc
Code:
```............................
i=957 iSum=213603
i=960 iSum=214560
i=963 iSum=215520
i=965 iSum=216483
i=966 iSum=217448
i=969 iSum=218414
i=970 iSum=219383
i=972 iSum=220353
i=975 iSum=221325
i=978 iSum=222300
i=980 iSum=223278
i=981 iSum=224258
i=984 iSum=225239
i=985 iSum=226223
i=987 iSum=227208
i=990 iSum=228195
i=993 iSum=229185
i=995 iSum=230178
i=996 iSum=231173
i=999 iSum=232169

The sum of all the multiples of 3 or 5 below 1000: 233168```
i tested

consider making your datatype to unsigned since you are never interested in dealing with -ve numbers in this scenerio.

also consider i to be register data-type...as you are using that for iteration, it will be faster.

8. also consider i to be register data-type...as you are using that for iteration, it will be faster.
Unless you're actually using a modern compiler that would detect commonly used variables and optimize them into registers automatically.

Seriously, unless you're doing assembly or embedded programming where you don't have a very good compiler, you probably shouldn't need to use the "register" keyword these days . . . .

Along with conio.h, getch() and clrscr() are non-standard. Instead of getch(), you can make use of getchar() (see the FAQ). And I really think that you don't need clrscr() . . . but if you really, really want your program to clear the screen after it exits, I suppose you could call system("cls"). That's not much better than clrscr(), though.

9. Originally Posted by creeping death
it runs perfectly well in gcc
Code:
```............................
i=957 iSum=213603
i=960 iSum=214560
i=963 iSum=215520
i=965 iSum=216483
i=966 iSum=217448
i=969 iSum=218414
i=970 iSum=219383
i=972 iSum=220353
i=975 iSum=221325
i=978 iSum=222300
i=980 iSum=223278
i=981 iSum=224258
i=984 iSum=225239
i=985 iSum=226223
i=987 iSum=227208
i=990 iSum=228195
i=993 iSum=229185
i=995 iSum=230178
i=996 iSum=231173
i=999 iSum=232169

The sum of all the multiples of 3 or 5 below 1000: 233168```
i tested
I disagree that it runs perfectly. Why is iSum different from the last line and which total is correct? Your sample output raises more debugging concerns.

10. Originally Posted by dwks
Seriously, unless you're doing assembly or embedded programming where you don't have a very good compiler, you probably shouldn't need to use the "register" keyword these days . . . .
And in fact doing so may slow your code down.

11. I tried using the register keyword several times cos I thought it would make things faster... It always turned out slower than ordinary variables. static variables generally seem to speed things up, but apparently they cripple the optimiser or something. I still use them now and again in functions that get called very often.

Can also be obtained without loops:
Code:
```q = 999 / 3;
sum = (q * q + q) / 2 * 3; // sum of multiples of 3 works out to 166833
q = 999 / 5;
sum += (q * q + q) / 2 * 5; // sum of multiples of 5 works out to 99500
q = 999 / 15;
sum -= (q * q + q) / 2 * 15; // sum of multiples of 15 works out to 33165```
( 166833 + 99500 - 33165 = 233168 )

</smartass>

13. Originally Posted by mike_g
I tried using the register keyword several times cos I thought it would make things faster... It always turned out slower than ordinary variables. static variables generally seem to speed things up, but apparently they cripple the optimiser or something. I still use them now and again in functions that get called very often.
Static variables within a function may not be so bad for the optimizer, as they are not truly GLOBAL variables, so the optimizer can know what happens to the variable (as long as the variable is not passed outside in the form of a pointer to or some such).

--
Mats

14. Hi all,

Thanks a ton for all the help. I appreciate it! Finally I was able to successfully compile/run this program.

Turbo C 3.0 and 4.5 int overflow
Gcc on Ubuntu I think I have not yet installed all the components so it errored out

I tried Netbeans with cygwin/gcc magically it worked and also gave me the correct results.
Thank you,
Deepak

15. Originally Posted by whiteflags
I disagree that it runs perfectly. Why is iSum different from the last line and which total is correct? Your sample output raises more debugging concerns.
oO...what the...i didnt notice that. beats me...i dont see why that should happen...the OP should be more scared than you or I though....

And in fact doing so may slow your code down.
hmmm....i dont know

heres a pretty simple test...

Code:
```#include<stdio.h>

int main()
{
register int i=1;
while(i>0)
{
i++;
}
printf("%d",i);
}```
i measured the time it took ... 3 times
Code:
```[c_d@localhost C]\$ gcc product.c
[c_d@localhost C]\$ time ./a.out
-2147483648
real	0m8.141s
user	0m8.121s
sys	0m0.002s
[c_d@localhost C]\$ time ./a.out
-2147483648
real	0m8.116s
user	0m8.108s
sys	0m0.001s
[c_d@localhost C]\$ time ./a.out
-2147483648
real	0m8.121s
user	0m8.106s
sys	0m0.000s```
average(register variable)
realtime=8.126
usertime=8.111666667
systime=0.001

then i changed the program to
[code]
Code:
```#include<stdio.h>

int main()
{
int i=1;
while(i>0)
{
i++;
}
printf("%d",i);
}```
the time taken were
Code:
```[c_d@localhost C]\$ gcc product.c
[c_d@localhost C]\$ time ./a.out
-2147483648
real	0m8.152s
user	0m8.126s
sys	0m0.004s
[c_d@localhost C]\$ time ./a.out
-2147483648
real	0m8.167s
user	0m8.132s
sys	0m0.001s
[c_d@localhost C]\$ time ./a.out
-2147483648
real	0m8.151s
user	0m8.127s
sys	0m0.002s```
average:(normal int)
realtime=8.156666667
usertime=8.128333333
systime=0.002333333

then i modified to
Code:
```#include<stdio.h>

int main()
{
static int i=1;
while(i>0)
{
i++;
}
printf("%d",i);
}```
and the results were
Code:
```[c_d@localhost C]\$ gcc product.c
[c_d@localhost C]\$ time ./a.out
-2147483648
real	0m8.373s
user	0m8.362s
sys	0m0.000s
[c_d@localhost C]\$ time ./a.out
-2147483648
real	0m8.128s
user	0m8.122s
sys	0m0.001s
[c_d@localhost C]\$ time ./a.out
-2147483648
real	0m8.690s
user	0m8.667s
sys	0m0.003s```
average(static int)
realtime=8.397
usertime=8.383666667
systime=0.001333333

according to this little experiment...

performance of register int >int> static int

I tried using the register keyword several times cos I thought it would make things faster... It always turned out slower than ordinary variables. static variables generally seem to speed things up, but apparently they cripple the optimiser or something. I still use them now and again in functions that get called very often.
hmm...i heard that static should be used in functions that are called many times, like recursive functions...because...every time , instead of the variables initialising again and again , static would mean one time initialisation, which would save processing time...