0

I'm trying to write a prime generator that implements the sieve of Eratosthenes. However, it includes some composite numbers (such as 25, 49 and other multiples of 5 and 7) in the output.

Here's my code:

/*****
 * To find out prime numbers from 1 to 100 with a different procedure
 * Author:Udit Gupta
 * Date:20/08/2011
 */

#include<stdio.h>

int main() {
    int a[100],i,j,k,n;

    for(i=0;i<=99;i++)
        a[i] = i+1;  /*1 to 100 numbers are entered into array*/

    /*Here te actual logic starts .......*/
    j = 1;
    while ( (a[j] != 0) && (j!=50) ) {
        k = 1;
        n = a[j];

        while( (n * k) < 99) {
            a[j+(n*k)] = 0;
            k++;
        }

        j++;
    }

    /*To print output of the array*/
    for (i=0;i<=99;i++) {
        if ( a[i] != 0)
            printf("\n%d",a[i]);
    }

    return 0;
}

Here is the output ....

    
udit@udit-Dabba ~/Desktop/letusc/ch8 $ gcc -o Dd Dd.c -Wall
udit@udit-Dabba ~/Desktop/letusc/ch8 $ ./Dd

1 2 3 5 7 11 13 17 19 23 25 29 31 35 37 41 43 47 49 53 55 59 61 65 67 71 73 77 79 83 85 89 91 95 97

outis
  • 75,655
  • 22
  • 151
  • 221
Udit Gupta
  • 3,162
  • 11
  • 43
  • 71
  • 1 isn't a prime number, by the way... – DNA Aug 19 '11 at 21:50
  • have you tried using a debugger – pm100 Aug 19 '11 at 21:51
  • 2
    Why don't you try debugging your code to find out? – Oliver Charlesworth Aug 19 '11 at 21:52
  • @MByD: I think the problem is 1, 25, 35, 49, 55, 65, 77, 85, 91 and 95. – Omri Barel Aug 19 '11 at 21:53
  • @omri yes you are right... I have applied the logic acc. to what I thought is right if somebody could tell me what's wrong I have done ????? – Udit Gupta Aug 19 '11 at 21:57
  • Never mind the debugger if you're not familiar with it - just add printf's to show the values j,n, and the values being set to zero... – DNA Aug 19 '11 at 22:25
  • @DNA: that also has the advantage that you can see the relevant values all at once, instead of having to step many loops. – Rudy Velthuis Aug 19 '11 at 22:32
  • @DNA: this is the perfect time to learn interactive debugging. A short program, a simple yet subtle bug. There's a time for scaffolding, but this isn't it. – outis Aug 19 '11 at 22:45
  • @Udit: off topic, you can shorten the number of iterations of the outer loop by changing the upper bound from 50 to something much lower. See if you can figure out what and why (hint: 100 = 2 * 50 = 5 * 20 = 10 * 10). – outis Aug 19 '11 at 22:51

6 Answers6

1

1st hint: in a debugger, break on the n = a[j]; line. Run a few iterations. Does it ever stop when a[j] == 5?

udit@udit-Dabba ~/Desktop/letusc/ch8 $ gdb ./Dd
[GDB preamble elided]
(gdb) b main
Breakpoint 1 at 0x100000e63: file Dd.c, line 12.
(gdb) r
Starting program: /home/udit/Desktop/letusc/ch8/Dd
Reading symbols for shared libraries +. done

Breakpoint 1, main () at Dd.c:12
12      for(i=0;i<=99;i++)
(gdb) watch n
Hardware watchpoint 2: n
(gdb) c
Continuing.
Hardware watchpoint 2: n

Old value = 0
New value = 2
main () at Dd.c:21
21          while( (n * k) < 99) {
(gdb) c
Continuing.
Hardware watchpoint 2: n

Old value = 2
New value = 3
main () at Dd.c:21
21          while( (n * k) < 99) {
(gdb) p j
$1 = 2
(gdb) 

RMS's (no relation to that RMS) GDB tutorial includes a section on watchpoints, which the sample session above makes use of.

More hints to follow, as you need them.

outis
  • 75,655
  • 22
  • 151
  • 221
  • I am very new to programming and linux also pleas help me out how to debug the code on linux machine ?? – Udit Gupta Aug 19 '11 at 22:10
  • A guide would be best. Try [Linux software debugging with GDB](http://www.ibm.com/developerworks/library/l-gdb/), or search the web if that doesn't work for you. Short version: `gdb *executable*` to start gdb, `b (*function name*|*line number*)` to set a breakpoint, `r` to start the program running, `c` to continue after a breakpoint (until the next breakpoint), `p *expr*` to print the value of an expression (such as a variable name), `s` to step through a line. See [GDB Cheat Sheet](http://www.yolinux.com/TUTORIALS/GDB-Commands.html) for more info on commands. – outis Aug 19 '11 at 22:17
  • It never reaches n = 5. It stops far too early. – Rudy Velthuis Aug 19 '11 at 22:26
  • Thanks a lot.. I will try to work on debugging and got clear here...Its never executing for n=5 – Udit Gupta Aug 19 '11 at 22:32
1
while (n * k < 99) {
  a[j + n * k] = 0;
  k++;
}

This code is dangerous. You may well end up with j + n * k being larger than 99, which will overwrite arbitrary memory (or, strictly speaking, the behavior is undefined). Better be safe:

#include <assert.h>

...

while (n * k < 99) {
  int index = j + n * k;
  assert(0 <= index && index < 100);
  a[index] = 0;
  k++;
}
Roland Illig
  • 40,703
  • 10
  • 88
  • 121
1

Honestly, do yourself a favor and do a web search on "tutorial on gdb debugger". You'll get hundreds of hits. Then, sit down and have some fun learning a powerful tool that you will spend hundreds and hundreds of hours using if you continue to learn C, C++, or a dozen other computer languages. (I'm serious about the 'fun' part; I you don't find it fun, drop CS!)

Also do a search on 'ddd debugger'; this is a free OSS graphical front-end to gdb -- very nice, IMHO.

-k

Kevin Little
  • 12,436
  • 5
  • 39
  • 47
  • Indeed, running code line-by-line in gdb *is* fun. Often the problem line (or transition between lines) can just "jump out" at you. You may not instantly know what's wrong and how to fix it; but you can "sense" that something fishy just happened. Knowing *where* it's going wrong makes it easy to begin investigating *why*. – luser droog Aug 20 '11 at 06:13
0

hint ; look at what happened to 5 and hence 25

google will tell you how to use gdb - its not hard

a[j + n * k] = 0;

I think you mean

a[n * k] = 0;
pm100
  • 48,078
  • 23
  • 82
  • 145
0

You are storing your results (marking non-primes as zero) in the same array as you are reading from within the outer loop.

The number 4 gets (correctly) marked as non-prime, but this has the unwanted side-effect of terminiating your main loop (because a[j] ==0).

So you only process n=2 and n=3.

DNA
  • 42,007
  • 12
  • 107
  • 146
0

The problem is that the loop ends far too soon. if a == 3, a[j] == 0 and the loop ends. Change your main loop to:

for (j = 1; j < 50; j++) 
{
    k = 1;
    n = a[j];

    if (n != 0) 
        while (j + n * k <= 99) 
        {
            a[j + n * k] = 0;
            k++;
        }
}
Rudy Velthuis
  • 28,387
  • 5
  • 46
  • 94